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 static final String FAILED_TO_RETRIEVE_GRAPH_STATUS_IS = "Failed to retrieve graph. status is {}";
48 private static final String NO_EDGES_IN_GRAPH_FOR_CRITERIA = "No edges in graph for criteria";
49 private static final String FAILED_TO_CREATE_EDGE_FROM_TO = "Failed to create edge from [{}] to [{}]";
50 private TitanGraphClient titanClient;
51 private static Logger log = Logger.getLogger(TitanGenericDao.class.getName());
52 private static final String LOCK_NODE_PREFIX = "lock_";
54 public TitanGenericDao(TitanGraphClient titanClient) {
55 this.titanClient = titanClient;
56 log.info("** TitanGenericDao created");
59 public TitanOperationStatus commit() {
60 log.debug("doing commit.");
61 return titanClient.commit();
64 public TitanOperationStatus rollback() {
65 log.error("Going to execute rollback on graph.");
66 return titanClient.rollback();
69 public <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) {
71 if (result == null || result.isRight()) {
79 public Either<TitanGraph, TitanOperationStatus> getGraph() {
80 return titanClient.getGraph();
84 public boolean isGraphOpen() {
85 return titanClient.getHealth();
94 public <T extends GraphNode> Either<T, TitanOperationStatus> createNode(T node, Class<T> clazz) {
95 log.debug("try to create node for ID [{}]", node.getKeyValueId());
96 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
100 TitanGraph tGraph = graph.left().value();
102 Vertex vertex = tGraph.addVertex();
104 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
106 Map<String, Object> properties = node.toGraphMap();
107 if (properties != null) {
108 setProperties(vertex, properties);
110 Map<String, Object> newProps = getProperties(vertex);
111 newNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProps, clazz);
112 log.debug("created node for props : {}", newProps);
113 log.debug("Node was created for ID [{}]", node.getKeyValueId());
114 return Either.left(newNode);
116 } catch (Exception e) {
117 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
118 return Either.right(TitanGraphClient.handleTitanException(e));
122 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value());
123 return Either.right(graph.right().value());
127 public Either<TitanVertex, TitanOperationStatus> createNode(GraphNode node) {
128 log.debug("try to create node for ID [{}]", node.getKeyValueId());
129 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
130 if (graph.isLeft()) {
132 TitanGraph tGraph = graph.left().value();
134 TitanVertex vertex = tGraph.addVertex();
136 vertex.property(GraphPropertiesDictionary.LABEL.getProperty(), node.getLabel());
138 Map<String, Object> properties = node.toGraphMap();
139 if (properties != null) {
140 setProperties(vertex, properties);
142 log.debug("Node was created for ID [{}]", node.getKeyValueId());
143 return Either.left(vertex);
145 } catch (Exception e) {
146 log.debug("Failed to create Node for ID [{}]", node.getKeyValueId(), e);
147 return Either.right(TitanGraphClient.handleTitanException(e));
151 log.debug("Failed to create Node for ID [{}] {}", node.getKeyValueId(), graph.right().value());
152 return Either.right(graph.right().value());
161 public Either<GraphRelation, TitanOperationStatus> createRelation(GraphRelation relation) {
162 log.debug("try to create relation from [{}] to [{}] ", relation.getFrom(), relation.getTo());
164 RelationEndPoint from = relation.getFrom();
165 RelationEndPoint to = relation.getTo();
166 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
167 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
169 return createEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
173 private Either<GraphRelation, TitanOperationStatus> createEdge(String type, ImmutablePair<String, Object> from, ImmutablePair<String, Object> to, String fromLabel, String toLabel, Map<String, Object> properties) {
174 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
176 if (graph.isLeft()) {
178 Either<Vertex, TitanOperationStatus> fromV = getVertexByPropertyAndLabel(from.getKey(), from.getValue(), fromLabel);
179 if (fromV.isRight()) {
180 TitanOperationStatus error = fromV.right().value();
181 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
182 return Either.right(TitanOperationStatus.INVALID_ID);
184 return Either.right(error);
187 Either<Vertex, TitanOperationStatus> toV = getVertexByPropertyAndLabel(to.getKey(), to.getValue(), toLabel);
189 TitanOperationStatus error = toV.right().value();
190 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
191 return Either.right(TitanOperationStatus.INVALID_ID);
193 return Either.right(error);
197 Vertex fromVertex = fromV.left().value();
198 Vertex toVertex = toV.left().value();
199 Edge edge = fromVertex.addEdge(type, toVertex);
201 if (properties != null) {
203 setProperties(edge, properties);
206 Vertex vertexOut = edge.outVertex();
207 Vertex vertexIn = edge.inVertex();
209 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
210 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
212 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
214 return Either.left(newRelation);
215 } catch (Exception e) {
216 log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, from, to, e);
217 return Either.right(TitanGraphClient.handleTitanException(e));
220 log.debug("Failed to create edge from [{}] to [{}] {}", from, to, graph.right().value());
221 return Either.right(graph.right().value());
225 public TitanOperationStatus createEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
227 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
228 } catch (Exception e) {
229 log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e);
230 return TitanGraphClient.handleTitanException(e);
232 return TitanOperationStatus.OK;
236 private Edge addEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
237 Edge edge = vertexOut.addEdge(type.getProperty(), vertexIn);
239 if (properties != null) {
241 setProperties(edge, properties);
247 * creates an identical edge in the graph
249 * @return the copy operation status
251 public Either<Edge, TitanOperationStatus> copyEdge(Vertex out, Vertex in, Edge edge) {
252 GraphEdgeLabels byName = GraphEdgeLabels.getByName(edge.label());
253 return this.saveEdge(out, in, byName, edgePropertiesToMap(edge));
256 private <V> Map<String, Object> edgePropertiesToMap(Edge edge) {
257 Iterable<Property<Object>> propertiesIterable = edge::properties;
258 return StreamSupport.stream(propertiesIterable.spliterator(), false).collect(Collectors.toMap(Property::key, Property::value));
261 public Either<Edge, TitanOperationStatus> saveEdge(Vertex vertexOut, Vertex vertexIn, GraphEdgeLabels type, Map<String, Object> properties) {
263 Edge edge = addEdge(vertexOut, vertexIn, type, properties);
264 return Either.left(edge);
265 } catch (Exception e) {
266 log.debug(FAILED_TO_CREATE_EDGE_FROM_TO, vertexOut, vertexIn, e);
267 return Either.right(TitanGraphClient.handleTitanException(e));
272 public TitanOperationStatus createEdge(TitanVertex vertexOut, GraphNode to, GraphEdgeLabels type, Map<String, Object> properties) {
274 TitanVertex vertexIn;
275 Either<Vertex, TitanOperationStatus> toV = getVertexByPropertyAndLabel(to.getUniqueIdKey(), to.getUniqueId(), to.getLabel());
277 TitanOperationStatus error = toV.right().value();
278 if (TitanOperationStatus.NOT_FOUND.equals(error)) {
279 return TitanOperationStatus.INVALID_ID;
284 vertexIn = (TitanVertex) toV.left().value();
285 return createEdge(vertexOut, vertexIn, type, properties);
296 public Either<GraphRelation, TitanOperationStatus> createRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map<String, Object> properties) {
297 log.debug("try to create relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
298 return createEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
301 public Either<GraphRelation, TitanOperationStatus> replaceRelationLabel(GraphNode from, GraphNode to, GraphEdgeLabels label, GraphEdgeLabels newLabel) {
303 log.debug("try to replace relation {} to {} from [{}] to [{}]", label.name(), newLabel.name(), from.getKeyValueId(), to.getKeyValueId());
304 Either<GraphRelation, TitanOperationStatus> getRelationResult = getRelation(from, to, label);
305 if (getRelationResult.isRight()) {
306 return getRelationResult;
309 GraphRelation origRelation = getRelationResult.left().value();
310 Either<GraphRelation, TitanOperationStatus> createRelationResult = createRelation(from, to, newLabel, origRelation.toGraphMap());
311 if (createRelationResult.isRight()) {
312 return createRelationResult;
315 Either<GraphRelation, TitanOperationStatus> deleteRelationResult = deleteRelation(origRelation);
316 if (deleteRelationResult.isRight()) {
317 return deleteRelationResult;
319 return Either.left(createRelationResult.left().value());
329 public <T extends GraphNode> Either<T, TitanOperationStatus> getNode(String keyName, Object keyValue, Class<T> clazz) {
331 log.debug("Try to get node for key [{}] with value [{}] ", keyName, keyValue);
333 Either<TitanVertex, TitanOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
335 if (vertexByProperty.isLeft()) {
337 Vertex vertex = vertexByProperty.left().value();
338 Map<String, Object> properties = getProperties(vertex);
339 T node = GraphElementFactory.createElement((String) properties.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, properties, clazz);
340 return Either.left(node);
341 } catch (Exception e) {
342 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, e);
343 return Either.right(TitanGraphClient.handleTitanException(e));
346 log.debug("Failed to get node for key [{}] with value [{}] ", keyName, keyValue, vertexByProperty.right().value());
347 return Either.right(vertexByProperty.right().value());
358 public Either<GraphRelation, TitanOperationStatus> getRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
359 log.debug("try to get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
361 Either<Edge, TitanOperationStatus> edge = getEdgeByNodes(from, to, label);
365 Map<String, Object> properties = getProperties(edge.left().value());
366 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, from, to);
367 return Either.left(relation);
368 } catch (Exception e) {
369 log.debug("Failed to get get relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId(), e);
370 return Either.right(TitanGraphClient.handleTitanException(e));
373 log.debug("Failed to get get relation from [{}] to [{}] {}", from.getKeyValueId(), to.getKeyValueId(), edge.right().value());
374 return Either.right(edge.right().value());
378 public Either<Edge, TitanOperationStatus> getEdgeByNodes(GraphNode from, GraphNode to, GraphEdgeLabels label) {
379 ImmutablePair<String, Object> keyValueIdFrom = from.getKeyValueId();
380 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
382 return getEdgeByVerticies(keyValueIdFrom.getKey(), keyValueIdFrom.getValue(), keyValueIdTo.getKey(), keyValueIdTo.getValue(), label.getProperty());
385 public Either<GraphRelation, TitanOperationStatus> deleteIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
387 Either<Edge, TitanOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
388 if (edgeByCriteria.isLeft()) {
389 Either<TitanGraph, TitanOperationStatus> graph = getGraph();
390 if (graph.isLeft()) {
391 Edge edge = edgeByCriteria.left().value();
392 log.debug("delete edge {} to {} ", label.getProperty(), to.getUniqueId());
394 Map<String, Object> properties = getProperties(edge);
395 Vertex fromVertex = edge.outVertex();
396 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
397 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
398 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
399 return Either.left(relation);
401 log.debug("failed to get graph");
402 return Either.right(graph.right().value());
406 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
407 return Either.right(edgeByCriteria.right().value());
412 public Either<GraphRelation, TitanOperationStatus> getIncomingRelationByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
414 Either<Edge, TitanOperationStatus> edgeByCriteria = getIncomingEdgeByCriteria(to, label, props);
415 if (edgeByCriteria.isLeft()) {
416 Either<TitanGraph, TitanOperationStatus> graph = getGraph();
417 if (graph.isLeft()) {
418 Edge edge = edgeByCriteria.left().value();
419 Map<String, Object> properties = getProperties(edge);
420 Vertex fromVertex = edge.outVertex();
421 String fromLabel = fromVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
422 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(fromVertex), GraphNode.class);
423 GraphRelation relation = GraphElementFactory.createRelation(label.getProperty(), properties, nodeFrom, to);
424 return Either.left(relation);
426 log.debug("failed to get graph");
427 return Either.right(graph.right().value());
431 log.debug("failed to find edge {} to {}", label.getProperty(), to.getUniqueId());
432 return Either.right(edgeByCriteria.right().value());
437 public Either<Edge, TitanOperationStatus> getIncomingEdgeByCriteria(GraphNode to, GraphEdgeLabels label, Map<String, Object> props) {
439 ImmutablePair<String, Object> keyValueIdTo = to.getKeyValueId();
441 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(keyValueIdTo.getKey(), keyValueIdTo.getValue());
442 if (vertexFrom.isRight()) {
443 return Either.right(vertexFrom.right().value());
445 Vertex vertex = vertexFrom.left().value();
446 TitanVertex titanVertex = (TitanVertex) vertex;
447 TitanVertexQuery<?> query = titanVertex.query();
448 query = query.labels(label.getProperty());
450 if (props != null && !props.isEmpty()) {
451 for (Map.Entry<String, Object> entry : props.entrySet()) {
452 query = query.has(entry.getKey(), entry.getValue());
455 Edge matchingEdge = null;
456 Iterable<TitanEdge> edges = query.edges();
458 log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA);
459 return Either.right(TitanOperationStatus.NOT_FOUND);
461 Iterator<TitanEdge> eIter = edges.iterator();
462 if (eIter.hasNext()) {
463 matchingEdge = eIter.next();
466 if (matchingEdge == null) {
467 log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA);
468 return Either.right(TitanOperationStatus.NOT_FOUND);
470 return Either.left(matchingEdge);
473 public Either<Edge, TitanOperationStatus> getEdgeByVerticies(String keyNameFrom, Object keyValueFrom, String keyNameTo, Object keyValueTo, String label) {
474 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
476 if (graph.isLeft()) {
478 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(keyNameFrom, keyValueFrom);
479 if (vertexFrom.isRight()) {
480 return Either.right(vertexFrom.right().value());
482 Iterable<TitanEdge> edges = vertexFrom.left().value().query().labels(label).edges();
483 Iterator<TitanEdge> eIter = edges.iterator();
484 while (eIter.hasNext()) {
485 Edge edge = eIter.next();
486 Vertex vertexIn = edge.inVertex();
487 if (vertexIn.value(keyNameTo) != null && vertexIn.value(keyNameTo).equals(keyValueTo) && label.equals(edge.label())) {
488 return Either.left(edge);
491 log.debug("No relation in graph from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo);
492 return Either.right(TitanOperationStatus.NOT_FOUND);
493 } catch (Exception e) {
494 log.debug("Failed to get get relation from [{}={}] to [{}={}]", keyNameFrom, keyValueFrom, keyNameTo, keyValueTo, e);
495 return Either.right(TitanGraphClient.handleTitanException(e));
498 return Either.right(graph.right().value());
502 public Either<List<Edge>, TitanOperationStatus> getEdgesForNode(GraphNode node, Direction requestedDirection) {
504 Either<List<Edge>, TitanOperationStatus> result;
506 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
507 Either<TitanVertex, TitanOperationStatus> eitherVertex = getVertexByProperty(keyValueId.getKey(), keyValueId.getValue());
509 if (eitherVertex.isLeft()) {
510 List<Edge> edges = prepareEdgesList(eitherVertex.left().value(), requestedDirection);
512 result = Either.left(edges);
514 result = Either.right(eitherVertex.right().value());
519 private List<Edge> prepareEdgesList(Vertex vertex, Direction requestedDirection) {
520 List<Edge> edges = new ArrayList<>();
521 Iterator<TitanEdge> edgesItr = ((TitanVertex) vertex).query().edges().iterator();
522 while (edgesItr.hasNext()) {
523 Edge edge = edgesItr.next();
524 Direction currEdgeDirection = getEdgeDirection(vertex, edge);
525 if (currEdgeDirection == requestedDirection || requestedDirection == Direction.BOTH) {
533 private Direction getEdgeDirection(Vertex vertex, Edge edge) {
535 Vertex vertexOut = edge.outVertex();
536 if (vertexOut.equals(vertex)) {
537 result = Direction.OUT;
539 result = Direction.IN;
553 public Either<GraphRelation, TitanOperationStatus> updateRelation(GraphNode from, GraphNode to, GraphEdgeLabels label, Map<String, Object> properties) {
554 log.debug("try to update relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
555 return updateEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel(), properties);
558 private Either<GraphRelation, TitanOperationStatus> updateEdge(String type, ImmutablePair<String, Object> from, ImmutablePair<String, Object> to, String fromLabel, String toLabel, Map<String, Object> properties) {
560 Either<Edge, TitanOperationStatus> edgeS = getEdgeByVerticies(from.getKey(), from.getValue(), to.getKey(), to.getValue(), type);
561 if (edgeS.isLeft()) {
564 Edge edge = edgeS.left().value();
565 if (properties != null) {
566 setProperties(edge, properties);
569 Vertex vertexOut = edge.outVertex();
570 Vertex vertexIn = edge.inVertex();
572 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
573 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
575 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
576 if (log.isDebugEnabled()) {
577 log.debug("Relation was updated from [{}] to [{}] ", from, to);
579 return Either.left(newRelation);
580 } catch (Exception e) {
581 if (log.isDebugEnabled()) {
582 log.debug("Failed to update relation from [{}] to [{}] ", from, to, e);
584 return Either.right(TitanGraphClient.handleTitanException(e));
587 if (log.isDebugEnabled()) {
588 log.debug("Failed to update relation from [{}] to [{}] {}", from, to, edgeS.right().value());
590 return Either.right(edgeS.right().value());
599 public Either<GraphRelation, TitanOperationStatus> updateRelation(GraphRelation relation) {
600 log.debug("try to update relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
601 RelationEndPoint from = relation.getFrom();
602 RelationEndPoint to = relation.getTo();
603 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
604 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
606 return updateEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName(), relation.toGraphMap());
610 private Either<Vertex, TitanOperationStatus> getVertexByPropertyAndLabel(String name, Object value, String label) {
612 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
613 if (graph.isLeft()) {
615 TitanGraph tGraph = graph.left().value();
617 @SuppressWarnings("unchecked")
618 Iterable<TitanVertex> vertecies = tGraph.query().has(name, value).has(GraphPropertiesDictionary.LABEL.getProperty(), label).vertices();
620 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
621 if (iterator.hasNext()) {
622 Vertex vertex = iterator.next();
623 return Either.left(vertex);
625 if (log.isDebugEnabled()) {
626 log.debug("No vertex in graph for key =" + name + " and value = " + value + " label = " + label);
628 return Either.right(TitanOperationStatus.NOT_FOUND);
629 } catch (Exception e) {
630 if (log.isDebugEnabled()) {
631 log.debug("Failed to get vertex in graph for key ={} and value = {} label = {}",name,value,label);
633 return Either.right(TitanGraphClient.handleTitanException(e));
637 if (log.isDebugEnabled()) {
638 log.debug("No vertex in graph for key ={} and value = {} label = {} error : {}",name,value,label,graph.right().value());
640 return Either.right(graph.right().value());
644 public Either<TitanVertex, TitanOperationStatus> getVertexByProperty(String name, Object value) {
646 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
648 if (log.isDebugEnabled()) {
649 log.debug("No vertex in graph for key = {} and value = {}", name, value);
651 return Either.right(TitanOperationStatus.NOT_FOUND);
653 if (graph.isLeft()) {
655 TitanGraph tGraph = graph.left().value();
657 @SuppressWarnings("unchecked")
658 Iterable<TitanVertex> vertecies = tGraph.query().has(name, value).vertices();
660 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
661 if (iterator.hasNext()) {
662 TitanVertex vertex = iterator.next();
663 return Either.left(vertex);
665 if (log.isDebugEnabled()) {
666 log.debug("No vertex in graph for key ={} and value = {}", name, value);
668 return Either.right(TitanOperationStatus.NOT_FOUND);
670 } catch (Exception e) {
671 if (log.isDebugEnabled()) {
672 log.debug("Failed to get vertex in graph for key = {} and value = ", name, value);
674 return Either.right(TitanGraphClient.handleTitanException(e));
677 if (log.isDebugEnabled()) {
678 log.debug("No vertex in graph for key = {} and value = {} error : {}", name, value, graph.right().value());
680 return Either.right(graph.right().value());
684 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> hasProps, Map<String, Object> hasNotProps, Class<T> clazz) {
685 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
686 if (graph.isLeft()) {
688 TitanGraph tGraph = graph.left().value();
690 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
691 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
693 if (hasProps != null && !hasProps.isEmpty()) {
694 for (Map.Entry<String, Object> entry : hasProps.entrySet()) {
695 query = query.has(entry.getKey(), entry.getValue());
698 if (hasNotProps != null && !hasNotProps.isEmpty()) {
699 for (Map.Entry<String, Object> entry : hasNotProps.entrySet()) {
700 query = query.hasNot(entry.getKey(), entry.getValue());
703 Iterable<TitanVertex> vertices = query.vertices();
704 if (vertices == null) {
705 return Either.right(TitanOperationStatus.NOT_FOUND);
708 Iterator<TitanVertex> iterator = vertices.iterator();
709 List<T> result = new ArrayList<>();
711 while (iterator.hasNext()) {
712 Vertex vertex = iterator.next();
714 Map<String, Object> newProp = getProperties(vertex);
716 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
719 if (log.isDebugEnabled()) {
720 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties has = {}, properties hasNot = {} is {}", type, hasProps, hasNotProps, result.size());
722 if (result.size() == 0) {
723 return Either.right(TitanOperationStatus.NOT_FOUND);
726 return Either.left(result);
727 } catch (Exception e) {
728 if (log.isDebugEnabled()) {
729 log.debug("Failed get by criteria for type = {}", type, e);
731 return Either.right(TitanGraphClient.handleTitanException(e));
735 if (log.isDebugEnabled()) {
736 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
738 return Either.right(graph.right().value());
742 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Class<T> clazz, List<ImmutableTriple<QueryType, String, Object>> props) {
743 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
744 if (graph.isLeft()) {
746 TitanGraph tGraph = graph.left().value();
748 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
749 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
750 for (ImmutableTriple<QueryType, String, Object> prop : props) {
751 if (QueryType.HAS.equals(prop.getLeft())) {
752 query = query.has(prop.getMiddle(), prop.getRight());
754 query = query.hasNot(prop.getMiddle(), prop.getRight());
757 Iterable<TitanVertex> vertices = query.vertices();
758 if (vertices == null) {
759 return Either.right(TitanOperationStatus.NOT_FOUND);
762 Iterator<TitanVertex> iterator = vertices.iterator();
763 List<T> result = new ArrayList<>();
765 while (iterator.hasNext()) {
766 Vertex vertex = iterator.next();
768 Map<String, Object> newProp = getProperties(vertex);
770 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
773 if (result.size() == 0) {
774 return Either.right(TitanOperationStatus.NOT_FOUND);
777 return Either.left(result);
778 } catch (Exception e) {
779 if (log.isDebugEnabled()) {
780 log.debug("Failed get by criteria for type = {}", type, e);
782 return Either.right(TitanGraphClient.handleTitanException(e));
786 if (log.isDebugEnabled()) {
787 log.debug("Failed get by criteria for type ={} error : {}", type, graph.right().value());
789 return Either.right(graph.right().value());
793 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteria(NodeTypeEnum type, Map<String, Object> props, Class<T> clazz) {
794 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
795 if (graph.isLeft()) {
797 TitanGraph tGraph = graph.left().value();
799 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
800 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
802 if (props != null && !props.isEmpty()) {
803 for (Map.Entry<String, Object> entry : props.entrySet()) {
804 query = query.has(entry.getKey(), entry.getValue());
807 Iterable<TitanVertex> vertices = query.vertices();
808 if (vertices == null) {
809 return Either.right(TitanOperationStatus.NOT_FOUND);
812 Iterator<TitanVertex> iterator = vertices.iterator();
813 List<T> result = new ArrayList<>();
815 while (iterator.hasNext()) {
816 Vertex vertex = iterator.next();
818 Map<String, Object> newProp = getProperties(vertex);
820 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
823 if (log.isDebugEnabled()) {
824 log.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
826 if (result.size() == 0) {
827 return Either.right(TitanOperationStatus.NOT_FOUND);
830 return Either.left(result);
831 } catch (Exception e) {
832 if (log.isDebugEnabled()) {
833 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
835 return Either.right(TitanGraphClient.handleTitanException(e));
839 if (log.isDebugEnabled()) {
840 log.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
842 return Either.right(graph.right().value());
846 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getByCriteriaWithPredicate(NodeTypeEnum type, Map<String, Entry<TitanPredicate, Object>> props, Class<T> clazz) {
847 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
848 if (graph.isLeft()) {
850 TitanGraph tGraph = graph.left().value();
852 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
853 query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName());
855 if (props != null && !props.isEmpty()) {
856 TitanPredicate predicate = null;
857 Object object = null;
858 for (Map.Entry<String, Entry<TitanPredicate, Object>> entry : props.entrySet()) {
859 predicate = entry.getValue().getKey();
860 object = entry.getValue().getValue();
861 query = query.has(entry.getKey(), predicate, object);
864 Iterable<TitanVertex> vertices = query.vertices();
865 if (vertices == null) {
866 return Either.right(TitanOperationStatus.NOT_FOUND);
869 Iterator<TitanVertex> iterator = vertices.iterator();
870 List<T> result = new ArrayList<>();
872 while (iterator.hasNext()) {
873 Vertex vertex = iterator.next();
875 Map<String, Object> newProp = getProperties(vertex);
876 T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz);
879 if (result.size() == 0) {
880 return Either.right(TitanOperationStatus.NOT_FOUND);
882 if (log.isDebugEnabled()) {
883 log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props);
885 return Either.left(result);
886 } catch (Exception e) {
887 if (log.isDebugEnabled()) {
888 log.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
890 return Either.right(TitanGraphClient.handleTitanException(e));
894 if (log.isDebugEnabled()) {
895 log.debug("Failed get by criteria for type = {} and properties = {} error : {}", type, props, graph.right().value());
897 return Either.right(graph.right().value());
901 public <T extends GraphNode> Either<List<T>, TitanOperationStatus> getAll(NodeTypeEnum type, Class<T> clazz) {
902 return getByCriteria(type, null, clazz);
911 public <T extends GraphNode> Either<T, TitanOperationStatus> updateNode(GraphNode node, Class<T> clazz) {
912 log.debug("Try to update node for {}", node.getKeyValueId());
914 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
915 Either<Vertex, TitanOperationStatus> vertexByProperty = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel());
917 if (vertexByProperty.isLeft()) {
919 Vertex vertex = vertexByProperty.left().value();
921 Map<String, Object> mapProps = node.toGraphMap();
923 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
924 if (!entry.getKey().equals(node.getUniqueIdKey())) {
925 vertex.property(entry.getKey(), entry.getValue());
929 Either<Vertex, TitanOperationStatus> vertexByPropertyAndLabel = getVertexByPropertyAndLabel(keyValueId.getKey(), keyValueId.getValue(), node.getLabel());
930 if (vertexByPropertyAndLabel.isRight()) {
931 return Either.right(vertexByPropertyAndLabel.right().value());
933 Map<String, Object> newProp = getProperties(vertexByPropertyAndLabel.left().value());
934 T updateNode = GraphElementFactory.createElement(node.getLabel(), GraphElementTypeEnum.Node, newProp, clazz);
935 return Either.left(updateNode);
937 } catch (Exception e) {
938 if (log.isDebugEnabled()) {
939 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
941 return Either.right(TitanGraphClient.handleTitanException(e));
944 if (log.isDebugEnabled()) {
945 log.debug("Failed to update node for {} error :{}", node.getKeyValueId(), vertexByProperty.right().value());
947 return Either.right(vertexByProperty.right().value());
952 public TitanOperationStatus updateVertex(GraphNode node, Vertex vertex) {
953 log.debug("Try to update node for {}", node.getKeyValueId());
956 Map<String, Object> mapProps = node.toGraphMap();
958 for (Map.Entry<String, Object> entry : mapProps.entrySet()) {
959 if (!entry.getKey().equals(node.getUniqueIdKey())) {
960 vertex.property(entry.getKey(), entry.getValue());
964 } catch (Exception e) {
965 if (log.isDebugEnabled()) {
966 log.debug("Failed to update node for {}", node.getKeyValueId(), e);
968 return TitanGraphClient.handleTitanException(e);
970 return TitanOperationStatus.OK;
980 public <T extends GraphNode> Either<T, TitanOperationStatus> deleteNode(GraphNode node, Class<T> clazz) {
981 log.debug("Try to delete node for {}", node.getKeyValueId());
982 ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
983 return deleteNode(keyValueId.getKey(), keyValueId.getValue(), clazz);
993 public <T extends GraphNode> Either<T, TitanOperationStatus> deleteNode(String keyName, Object keyValue, Class<T> clazz) {
994 Either<TitanVertex, TitanOperationStatus> vertexByProperty = getVertexByProperty(keyName, keyValue);
996 if (vertexByProperty.isLeft()) {
998 Vertex vertex = vertexByProperty.left().value();
1000 Map<String, Object> properties = getProperties(vertex);
1001 if (properties != null) {
1002 String label = (String) properties.get(GraphPropertiesDictionary.LABEL.getProperty());
1004 T node = GraphElementFactory.createElement(label, GraphElementTypeEnum.Node, properties, clazz);
1006 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1007 if (graph.isLeft()) {
1008 TitanGraph tGraph = graph.left().value();
1011 return Either.right(graph.right().value());
1013 return Either.left(node);
1015 if (log.isDebugEnabled()) {
1016 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1018 return Either.right(TitanOperationStatus.MISSING_NODE_LABEL);
1021 if (log.isDebugEnabled()) {
1022 log.debug("Failed to delete node for {} = {} Missing label property on node", keyName, keyValue);
1024 return Either.right(TitanOperationStatus.MISSING_NODE_LABEL);
1026 } catch (Exception e) {
1027 if (log.isDebugEnabled()) {
1028 log.debug("Failed to delete node for {} = {}", keyName, keyValue, e);
1030 return Either.right(TitanGraphClient.handleTitanException(e));
1034 return Either.right(vertexByProperty.right().value());
1038 public Either<GraphRelation, TitanOperationStatus> deleteRelation(GraphRelation relation) {
1039 log.debug("try to delete relation from [{}] to [{}]", relation.getFrom(), relation.getTo());
1040 RelationEndPoint from = relation.getFrom();
1041 RelationEndPoint to = relation.getTo();
1042 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1043 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1045 return deleteEdge(relation.getType(), fromKeyId, toKeyId, from.getLabel().getName(), to.getLabel().getName());
1049 public Either<Boolean, TitanOperationStatus> isRelationExist(GraphNode from, GraphNode to, GraphEdgeLabels edgeLabel) {
1050 return getEdgeByNodes(from, to, edgeLabel)
1054 .bind(err -> err == TitanOperationStatus.NOT_FOUND ? Either.left(false): Either.right(err));
1057 public Either<GraphRelation, TitanOperationStatus> deleteRelation(GraphNode from, GraphNode to, GraphEdgeLabels label) {
1058 log.debug("try to delete relation from [{}] to [{}]", from.getKeyValueId(), to.getKeyValueId());
1059 return deleteEdge(label.getProperty(), from.getKeyValueId(), to.getKeyValueId(), from.getLabel(), to.getLabel());
1062 private Either<GraphRelation, TitanOperationStatus> deleteEdge(String type, ImmutablePair<String, Object> fromKeyId, ImmutablePair<String, Object> toKeyId, String fromLabel, String toLabel) {
1063 Either<Edge, TitanOperationStatus> edgeS = getEdgeByVerticies(fromKeyId.getKey(), fromKeyId.getValue(), toKeyId.getKey(), toKeyId.getValue(), type);
1064 if (edgeS.isLeft()) {
1066 Edge edge = edgeS.left().value();
1068 Vertex vertexOut = edge.outVertex();
1069 Vertex vertexIn = edge.inVertex();
1071 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1072 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1074 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1076 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1078 if (graph.isLeft()) {
1082 if (log.isDebugEnabled()) {
1083 log.debug("Failed to delete relation {} from {} to {} error : {}",type,fromKeyId,toKeyId,graph.right().value());
1085 return Either.right(graph.right().value());
1087 return Either.left(newRelation);
1088 } catch (Exception e) {
1089 if (log.isDebugEnabled()) {
1090 log.debug("Failed to delete relation {} from {} to {}", type, fromKeyId, toKeyId, e);
1092 return Either.right(TitanGraphClient.handleTitanException(e));
1095 if (log.isDebugEnabled()) {
1096 log.debug("Failed to delete relation {} from {} to {} error : {}", type, fromKeyId, toKeyId, edgeS.right().value());
1098 return Either.right(edgeS.right().value());
1102 public void setTitanGraphClient(TitanGraphClient titanGraphClient) {
1103 this.titanClient = titanGraphClient;
1106 public Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation(GraphRelation relation) {
1108 RelationEndPoint to = relation.getTo();
1109 ImmutablePair<String, Object> toKeyId = new ImmutablePair<>(to.getIdName(), to.getIdValue());
1111 return deleteIncomingEdge(relation.getType(), toKeyId);
1115 private Either<GraphRelation, TitanOperationStatus> deleteIncomingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1117 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1119 if (graph.isLeft()) {
1120 Either<TitanVertex, TitanOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1121 if (rootVertexResult.isLeft()) {
1122 Vertex rootVertex = rootVertexResult.left().value();
1123 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.IN, type);
1124 if (edgesIterator != null) {
1128 if (edgesIterator.hasNext()) {
1129 edge = edgesIterator.next();
1130 if (edgesIterator.hasNext()) {
1131 return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1134 return Either.right(TitanOperationStatus.NOT_FOUND);
1137 log.debug("Find the tail vertex of the edge of type {} to vertex {}", type, toKeyId);
1138 Vertex vertexOut = edge.outVertex();
1139 String fromLabel = vertexOut.value(GraphPropertiesDictionary.LABEL.getProperty());
1140 String toLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1141 log.debug("The label of the outgoing vertex is {}", fromLabel);
1142 GraphNode nodeOut = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(vertexOut), GraphNode.class);
1144 GraphNode nodeIn = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1146 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeOut, nodeIn);
1150 return Either.left(newRelation);
1153 return Either.right(TitanOperationStatus.NOT_FOUND);
1157 return Either.right(graph.right().value());
1161 return Either.right(graph.right().value());
1166 public Either<GraphRelation, TitanOperationStatus> deleteOutgoingRelation(GraphRelation relation) {
1168 RelationEndPoint from = relation.getFrom();
1169 ImmutablePair<String, Object> fromKeyId = new ImmutablePair<>(from.getIdName(), from.getIdValue());
1171 return deleteOutgoingEdge(relation.getType(), fromKeyId);
1175 private Either<GraphRelation, TitanOperationStatus> deleteOutgoingEdge(String type, ImmutablePair<String, Object> toKeyId) {
1177 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1179 if (graph.isLeft()) {
1180 Either<TitanVertex, TitanOperationStatus> rootVertexResult = getVertexByProperty(toKeyId.getKey(), toKeyId.getValue());
1181 if (rootVertexResult.isLeft()) {
1182 Vertex rootVertex = rootVertexResult.left().value();
1183 Iterator<Edge> edgesIterator = rootVertex.edges(Direction.OUT, type);
1184 if (edgesIterator != null) {
1188 if (edgesIterator.hasNext()) {
1189 edge = edgesIterator.next();
1190 if (edgesIterator.hasNext()) {
1191 return Either.right(TitanOperationStatus.MULTIPLE_EDGES_WITH_SAME_LABEL);
1194 return Either.right(TitanOperationStatus.NOT_FOUND);
1197 log.debug("Find the tail vertex of the edge of type {} to vertex ", type, toKeyId);
1198 Vertex vertexIn = edge.inVertex();
1199 String toLabel = vertexIn.value(GraphPropertiesDictionary.LABEL.getProperty());
1200 String fromLabel = rootVertex.value(GraphPropertiesDictionary.LABEL.getProperty());
1201 log.debug("The label of the tail vertex is {}", toLabel);
1202 GraphNode nodeFrom = GraphElementFactory.createElement(fromLabel, GraphElementTypeEnum.Node, getProperties(rootVertex), GraphNode.class);
1204 GraphNode nodeTo = GraphElementFactory.createElement(toLabel, GraphElementTypeEnum.Node, getProperties(vertexIn), GraphNode.class);
1206 GraphRelation newRelation = GraphElementFactory.createRelation(edge.label(), getProperties(edge), nodeFrom, nodeTo);
1210 return Either.left(newRelation);
1213 return Either.right(TitanOperationStatus.NOT_FOUND);
1217 return Either.right(graph.right().value());
1221 return Either.right(graph.right().value());
1231 public TitanOperationStatus lockElement(String id, NodeTypeEnum type) {
1233 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1234 lockId.append(type.getName()).append("_").append(id);
1235 return lockNode(lockId.toString());
1238 public TitanOperationStatus lockElement(GraphNode node) {
1240 StringBuffer lockId = createLockElementId(node);
1242 return lockNode(lockId.toString());
1245 private TitanOperationStatus lockNode(String lockId) {
1246 TitanOperationStatus status = TitanOperationStatus.OK;
1248 GraphNodeLock lockNode = new GraphNodeLock(lockId);
1250 Either<GraphNodeLock, TitanOperationStatus> lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1251 if (lockNodeNew.isLeft()) {
1252 log.debug("before commit, Lock node created for {}", lockId);
1253 return titanClient.commit();
1255 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
1256 if (graph.isLeft()) {
1257 TitanGraph tGraph = graph.left().value();
1258 Either<TitanVertex, TitanOperationStatus> vertex = getVertexByProperty(lockNode.getUniqueIdKey(), lockNode.getUniqueId());
1259 if (vertex.isLeft()) {
1260 status = relockNode(lockNode, lockNodeNew, tGraph, vertex);
1262 status = vertex.right().value();
1265 status = graph.right().value();
1271 private TitanOperationStatus relockNode(GraphNodeLock lockNode, Either<GraphNodeLock, TitanOperationStatus> lockNodeNew, TitanGraph tGraph, Either<TitanVertex, TitanOperationStatus> vertex) {
1272 TitanOperationStatus status = TitanOperationStatus.OK;
1273 Long time = vertex.left().value().value(GraphPropertiesDictionary.CREATION_DATE.getProperty());
1274 Long lockTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getTitanLockTimeout();
1275 if (time + lockTimeout * 1000 < System.currentTimeMillis()) {
1276 log.debug("Found not released lock node with id {}", lockNode.getUniqueId());
1277 vertex.left().value().remove();
1278 lockNodeNew = createNode(lockNode, GraphNodeLock.class);
1279 if (lockNodeNew.isLeft()) {
1280 log.debug("Lock node created for {}", lockNode.getUniqueIdKey());
1281 return titanClient.commit();
1283 log.debug("Failed Lock node for {} . Commit transacton for deleted previous vertex .", lockNode.getUniqueIdKey());
1284 titanClient.commit();
1285 status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1288 log.debug("Failed Lock node for {} rollback transacton", lockNode.getUniqueIdKey());
1289 titanClient.rollback();
1290 status = checkLockError(lockNode.getUniqueIdKey(), lockNodeNew);
1295 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz, boolean withEdges) {
1297 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1299 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1300 if (graphRes.isRight()) {
1301 log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes);
1302 return Either.right(graphRes.right().value());
1305 TitanGraph titanGraph = graphRes.left().value();
1306 @SuppressWarnings("unchecked")
1307 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1308 if (vertices == null || !vertices.iterator().hasNext()) {
1309 return Either.right(TitanOperationStatus.INVALID_ID);
1312 Vertex rootVertex = vertices.iterator().next();
1314 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1315 if (edgesCreatorIterator != null) {
1316 while (edgesCreatorIterator.hasNext()) {
1317 Edge edge = edgesCreatorIterator.next();
1318 GraphEdge graphEdge = null;
1321 Map<String, Object> edgeProps = getProperties(edge);
1322 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1323 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1326 Vertex outgoingVertex = edge.inVertex();
1327 Map<String, Object> properties = getProperties(outgoingVertex);
1328 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1330 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1331 immutablePairs.add(immutablePair);
1335 if (immutablePairs.isEmpty()) {
1336 return Either.right(TitanOperationStatus.NOT_FOUND);
1339 return Either.left(immutablePairs);
1343 public Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> getChildrenVertecies(String key, String uniqueId, GraphEdgeLabels edgeType) {
1345 List<ImmutablePair<TitanVertex, Edge>> immutablePairs = new ArrayList<>();
1347 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1348 if (graphRes.isRight()) {
1349 log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes);
1350 return Either.right(graphRes.right().value());
1353 TitanGraph titanGraph = graphRes.left().value();
1354 @SuppressWarnings("unchecked")
1355 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1356 if (vertices == null || !vertices.iterator().hasNext()) {
1357 return Either.right(TitanOperationStatus.INVALID_ID);
1360 Vertex rootVertex = vertices.iterator().next();
1362 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty());
1363 if (edgesCreatorIterator != null) {
1364 while (edgesCreatorIterator.hasNext()) {
1365 Edge edge = edgesCreatorIterator.next();
1366 TitanVertex vertex = (TitanVertex) edge.inVertex();
1368 ImmutablePair<TitanVertex, Edge> immutablePair = new ImmutablePair<>(vertex, edge);
1369 immutablePairs.add(immutablePair);
1372 if (immutablePairs.isEmpty()) {
1373 return Either.right(TitanOperationStatus.NOT_FOUND);
1376 return Either.left(immutablePairs);
1380 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1381 return this.getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz, true);
1384 private TitanOperationStatus checkLockError(String lockId, Either<GraphNodeLock, TitanOperationStatus> lockNodeNew) {
1385 TitanOperationStatus status;
1386 TitanOperationStatus error = lockNodeNew.right().value();
1387 log.debug("Failed to Lock node for {} error = {}", lockId, error);
1388 if (error.equals(TitanOperationStatus.TITAN_SCHEMA_VIOLATION) || error.equals(TitanOperationStatus.ILLEGAL_ARGUMENT)) {
1389 status = TitanOperationStatus.ALREADY_LOCKED;
1401 public TitanOperationStatus releaseElement(GraphNode node) {
1402 StringBuffer lockId = createLockElementId(node);
1404 return unlockNode(lockId);
1407 private TitanOperationStatus unlockNode(StringBuffer lockId) {
1408 GraphNodeLock lockNode = new GraphNodeLock(lockId.toString());
1410 Either<GraphNodeLock, TitanOperationStatus> lockNodeNew = deleteNode(lockNode, GraphNodeLock.class);
1411 if (lockNodeNew.isLeft()) {
1412 log.debug("Lock node released for lock id = {}", lockId);
1413 return titanClient.commit();
1415 titanClient.rollback();
1416 TitanOperationStatus error = lockNodeNew.right().value();
1417 log.debug("Failed to Release node for lock id {} error = {}", lockId, error);
1422 public TitanOperationStatus releaseElement(String id, NodeTypeEnum type) {
1423 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1424 lockId.append(type.getName()).append("_").append(id);
1425 return unlockNode(lockId);
1428 private StringBuffer createLockElementId(GraphNode node) {
1429 StringBuffer lockId = new StringBuffer(LOCK_NODE_PREFIX);
1430 lockId.append(node.getLabel()).append("_").append(node.getUniqueId());
1434 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, TitanOperationStatus> getChild(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1436 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1438 if (childrenNodes.isRight()) {
1439 return Either.right(childrenNodes.right().value());
1442 List<ImmutablePair<T, GraphEdge>> value = childrenNodes.left().value();
1444 if (value.size() > 1) {
1445 return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1448 return Either.left(value.get(0));
1452 public ImmutablePair<TitanVertex, Edge> getChildVertex(TitanVertex vertex, GraphEdgeLabels edgeType) {
1454 ImmutablePair<TitanVertex, Edge> pair = null;
1455 Iterator<Edge> edges = vertex.edges(Direction.OUT, edgeType.getProperty());
1456 if (edges.hasNext()) {
1457 // get only first edge
1458 Edge edge = edges.next();
1459 pair = new ImmutablePair<>((TitanVertex) edge.inVertex(), edge);
1464 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getParentNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1466 List<ImmutablePair<T, GraphEdge>> immutablePairs = new ArrayList<>();
1469 GraphEdge graphEdge = null;
1471 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
1472 if (graphRes.isRight()) {
1473 log.error(FAILED_TO_RETRIEVE_GRAPH_STATUS_IS, graphRes);
1474 return Either.right(graphRes.right().value());
1477 TitanGraph titanGraph = graphRes.left().value();
1478 @SuppressWarnings("unchecked")
1479 Iterable<TitanVertex> vertices = titanGraph.query().has(key, uniqueId).vertices();
1480 if (vertices == null || !vertices.iterator().hasNext()) {
1481 return Either.right(TitanOperationStatus.INVALID_ID);
1484 Vertex rootVertex = vertices.iterator().next();
1486 Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.IN, edgeType.name());
1487 if (edgesCreatorIterator != null) {
1488 while (edgesCreatorIterator.hasNext()) {
1489 Edge edge = edgesCreatorIterator.next();
1490 Map<String, Object> edgeProps = getProperties(edge);
1491 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1492 graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1494 Vertex outgoingVertex = edge.outVertex();
1495 Map<String, Object> properties = getProperties(outgoingVertex);
1496 data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1498 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1499 immutablePairs.add(immutablePair);
1503 if (immutablePairs.isEmpty()) {
1504 return Either.right(TitanOperationStatus.NOT_FOUND);
1507 return Either.left(immutablePairs);
1511 public <T extends GraphNode> Either<ImmutablePair<T, GraphEdge>, TitanOperationStatus> getParentNode(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1513 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> parentNodesRes = this.getParentNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1515 if (parentNodesRes.isRight()) {
1516 log.debug("failed to get edge key:{} uniqueId:{} edgeType {} nodeTypeEnum: {}, reason:{}", key, uniqueId, edgeType, nodeTypeEnum, parentNodesRes.right().value());
1517 return Either.right(parentNodesRes.right().value());
1520 List<ImmutablePair<T, GraphEdge>> value = parentNodesRes.left().value();
1522 if (value.size() > 1) {
1523 return Either.right(TitanOperationStatus.MULTIPLE_CHILDS_WITH_SAME_EDGE);
1526 return Either.left(value.get(0));
1529 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) {
1531 Either<Edge, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(key, uniqueId, edgeType, edgeProperties);
1532 if (outgoingEdgeByCriteria.isRight()) {
1533 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1534 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}" + uniqueId, edgeType, edgeProperties);
1535 return Either.right(status);
1538 Edge edge = outgoingEdgeByCriteria.left().value();
1539 Map<String, Object> edgeProps = getProperties(edge);
1540 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1541 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1543 Vertex outgoingVertex = edge.inVertex();
1544 Map<String, Object> properties = getProperties(outgoingVertex);
1545 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1547 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1549 return Either.left(immutablePair);
1552 public Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getChildByEdgeCriteria(TitanVertex vertex, GraphEdgeLabels edgeType, Map<String, Object> edgeProperties) {
1554 Either<Edge, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgeByCriteria(vertex, edgeType, edgeProperties);
1555 if (outgoingEdgeByCriteria.isRight()) {
1556 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1557 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertex, edgeType, edgeProperties);
1558 return Either.right(status);
1560 Edge edge = outgoingEdgeByCriteria.left().value();
1562 TitanVertex outgoingVertex = (TitanVertex) edge.inVertex();
1564 ImmutablePair<TitanVertex, Edge> immutablePair = new ImmutablePair<>(outgoingVertex, edge);
1566 return Either.left(immutablePair);
1569 public Either<Edge, TitanOperationStatus> getOutgoingEdgeByCriteria(String key, String value, GraphEdgeLabels label, Map<String, Object> props) {
1571 Either<TitanVertex, TitanOperationStatus> vertexFrom = getVertexByProperty(key, value);
1572 if (vertexFrom.isRight()) {
1573 TitanOperationStatus status = vertexFrom.right().value();
1574 if (status == TitanOperationStatus.NOT_FOUND) {
1575 return Either.right(TitanOperationStatus.INVALID_ID);
1577 return Either.right(status);
1580 return getOutgoingEdgeByCriteria(vertexFrom.left().value(), label, props);
1583 public Either<Edge, TitanOperationStatus> getOutgoingEdgeByCriteria(TitanVertex vertex, GraphEdgeLabels label, Map<String, Object> props) {
1585 TitanVertexQuery<?> query = vertex.query();
1586 query = query.direction(Direction.OUT).labels(label.getProperty());
1588 if (props != null && !props.isEmpty()) {
1589 for (Map.Entry<String, Object> entry : props.entrySet()) {
1590 query = query.has(entry.getKey(), entry.getValue());
1593 Edge matchingEdge = null;
1594 Iterable<TitanEdge> edges = query.edges();
1595 if (edges == null) {
1596 log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA);
1597 return Either.right(TitanOperationStatus.NOT_FOUND);
1599 Iterator<TitanEdge> eIter = edges.iterator();
1600 if (eIter.hasNext()) {
1601 matchingEdge = eIter.next();
1604 if (matchingEdge == null) {
1605 log.debug(NO_EDGES_IN_GRAPH_FOR_CRITERIA);
1606 return Either.right(TitanOperationStatus.NOT_FOUND);
1608 return Either.left(matchingEdge);
1611 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> deleteChildrenNodes(String key, String uniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz) {
1613 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1615 Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> childrenNodesRes = getChildrenNodes(key, uniqueId, edgeType, nodeTypeEnum, clazz);
1617 if (childrenNodesRes.isRight()) {
1618 TitanOperationStatus status = childrenNodesRes.right().value();
1619 return Either.right(status);
1622 List<ImmutablePair<T, GraphEdge>> list = childrenNodesRes.left().value();
1623 for (ImmutablePair<T, GraphEdge> pair : list) {
1624 T node = pair.getKey();
1625 Either<T, TitanOperationStatus> deleteNodeRes = this.deleteNode(node, clazz);
1626 if (deleteNodeRes.isRight()) {
1627 TitanOperationStatus status = deleteNodeRes.right().value();
1628 log.error("Failed to delete node {} . status is {}", node, status);
1629 return Either.right(status);
1631 ImmutablePair<T, GraphEdge> deletedPair = new ImmutablePair<>(node, pair.getValue());
1632 result.add(deletedPair);
1635 return Either.left(result);
1639 public void setProperties(Element element, Map<String, Object> properties) {
1641 if (properties != null && !properties.isEmpty()) {
1643 Object[] propertyKeyValues = new Object[properties.size() * 2];
1645 for (Entry<String, Object> entry : properties.entrySet()) {
1646 propertyKeyValues[i++] = entry.getKey();
1647 propertyKeyValues[i++] = entry.getValue();
1650 ElementHelper.attachProperties(element, propertyKeyValues);
1656 public Map<String, Object> getProperties(Element element) {
1658 Map<String, Object> result = new HashMap<>();
1660 if (element != null && element.keys() != null && element.keys().size() > 0) {
1661 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
1663 for (Entry<String, Property> entry : propertyMap.entrySet()) {
1664 String key = entry.getKey();
1665 Object value = entry.getValue().value();
1667 result.put(key, value);
1673 public Object getProperty(TitanVertex vertex, String key) {
1674 PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key);
1675 return vertex.valueOrNull(propertyKey);
1678 public Object getProperty(Edge edge, String key) {
1679 Object value = null;
1680 Property<Object> property = edge.property(key);
1681 if (property != null) {
1682 return property.orElse(null);
1687 public <T extends GraphNode> Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> getChildrenByEdgeCriteria(Vertex vertex, String vertexUniqueId, GraphEdgeLabels edgeType, NodeTypeEnum nodeTypeEnum, Class<T> clazz,
1688 Map<String, Object> edgeProperties) {
1690 List<ImmutablePair<T, GraphEdge>> result = new ArrayList<>();
1692 Either<List<Edge>, TitanOperationStatus> outgoingEdgeByCriteria = getOutgoingEdgesByCriteria(vertex, edgeType, edgeProperties);
1693 if (outgoingEdgeByCriteria.isRight()) {
1694 TitanOperationStatus status = outgoingEdgeByCriteria.right().value();
1695 log.debug("Cannot find outgoing edge from vertex {} with label {} and properties {}", vertexUniqueId, edgeType, edgeProperties);
1696 return Either.right(status);
1699 List<Edge> edges = outgoingEdgeByCriteria.left().value();
1700 if (edges != null) {
1701 for (Edge edge : edges) {
1702 Map<String, Object> edgeProps = getProperties(edge);
1703 GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label());
1704 GraphEdge graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps);
1706 Vertex outgoingVertex = edge.inVertex();
1707 Map<String, Object> properties = getProperties(outgoingVertex);
1708 T data = GraphElementFactory.createElement(nodeTypeEnum.getName(), GraphElementTypeEnum.Node, properties, clazz);
1710 ImmutablePair<T, GraphEdge> immutablePair = new ImmutablePair<>(clazz.cast(data), graphEdge);
1711 result.add(immutablePair);
1715 return Either.left(result);
1718 public Either<List<Edge>, TitanOperationStatus> getOutgoingEdgesByCriteria(Vertex vertexFrom, GraphEdgeLabels label, Map<String, Object> props) {
1720 List<Edge> edgesResult = new ArrayList<>();
1722 TitanVertex titanVertex = (TitanVertex) vertexFrom;
1723 TitanVertexQuery<?> query = titanVertex.query();
1725 query = query.direction(Direction.OUT).labels(label.getProperty());
1727 if (props != null && !props.isEmpty()) {
1728 for (Map.Entry<String, Object> entry : props.entrySet()) {
1729 query = query.has(entry.getKey(), entry.getValue());
1733 Iterable<TitanEdge> edges = query.edges();
1734 Iterator<TitanEdge> eIter = edges.iterator();
1735 if (edges == null || !eIter.hasNext()) {
1736 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1737 return Either.right(TitanOperationStatus.NOT_FOUND);
1740 while (eIter.hasNext()) {
1741 Edge edge = eIter.next();
1742 edgesResult.add(edge);
1745 if (edgesResult.isEmpty()) {
1746 log.debug("No edges found in graph for criteria (label = {} properties={})", label.getProperty(), props);
1747 return Either.right(TitanOperationStatus.NOT_FOUND);
1749 return Either.left(edgesResult);