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.jsongraph;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
29 import java.util.Map.Entry;
31 import org.apache.commons.collections.MapUtils;
32 import org.apache.commons.lang3.tuple.ImmutablePair;
33 import org.apache.tinkerpop.gremlin.structure.Direction;
34 import org.apache.tinkerpop.gremlin.structure.Edge;
35 import org.apache.tinkerpop.gremlin.structure.Element;
36 import org.apache.tinkerpop.gremlin.structure.Property;
37 import org.apache.tinkerpop.gremlin.structure.Vertex;
38 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
39 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
40 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
41 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
42 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
43 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
44 import org.openecomp.sdc.be.dao.titan.TitanGraphClient;
45 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
46 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
47 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
48 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
49 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
50 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.springframework.beans.factory.annotation.Qualifier;
54 import org.springframework.stereotype.Component;
56 import com.thinkaurelius.titan.core.PropertyKey;
57 import com.thinkaurelius.titan.core.TitanEdge;
58 import com.thinkaurelius.titan.core.TitanGraph;
59 import com.thinkaurelius.titan.core.TitanGraphQuery;
60 import com.thinkaurelius.titan.core.TitanVertex;
61 import com.thinkaurelius.titan.core.TitanVertexQuery;
63 import fj.data.Either;
65 @Component("titan-dao")
66 public class TitanDao {
67 TitanGraphClient titanClient;
69 private static Logger logger = LoggerFactory.getLogger(TitanDao.class.getName());
71 public TitanDao(@Qualifier("titan-client") TitanGraphClient titanClient) {
72 this.titanClient = titanClient;
73 logger.info("** TitanDao created");
76 public TitanOperationStatus commit() {
77 logger.debug("doing commit.");
78 return titanClient.commit();
81 public TitanOperationStatus rollback() {
82 return titanClient.rollback();
85 public Either<TitanGraph, TitanOperationStatus> getGraph() {
86 return titanClient.getGraph();
94 public Either<GraphVertex, TitanOperationStatus> createVertex(GraphVertex graphVertex) {
95 logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId());
96 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
99 TitanGraph tGraph = graph.left().value();
101 TitanVertex vertex = tGraph.addVertex();
103 setVertexProperties(vertex, graphVertex);
105 graphVertex.setVertex(vertex);
107 return Either.left(graphVertex);
109 } catch (Exception e) {
110 logger.debug("Failed to create Node for ID [{}]", graphVertex.getUniqueId(), e);
111 return Either.right(TitanGraphClient.handleTitanException(e));
114 logger.debug("Failed to create vertex for ID [{}] {}", graphVertex.getUniqueId(), graph.right().value());
115 return Either.right(graph.right().value());
126 public Either<GraphVertex, TitanOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) {
127 return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll);
138 public Either<GraphVertex, TitanOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) {
140 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
141 if (graph.isLeft()) {
143 TitanGraph tGraph = graph.left().value();
145 @SuppressWarnings("unchecked")
146 Iterable<TitanVertex> vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
148 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
149 if (iterator.hasNext()) {
150 TitanVertex vertex = iterator.next();
151 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
153 return Either.left(graphVertex);
155 if (logger.isDebugEnabled()) {
156 logger.debug("No vertex in graph for key = {} and value = {} label = {}" + name, value, label);
158 return Either.right(TitanOperationStatus.NOT_FOUND);
159 } catch (Exception e) {
160 if (logger.isDebugEnabled()) {
161 logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
163 return Either.right(TitanGraphClient.handleTitanException(e));
167 if (logger.isDebugEnabled()) {
168 logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value());
170 return Either.right(graph.right().value());
179 public Either<GraphVertex, TitanOperationStatus> getVertexById(String id) {
180 return getVertexById(id, JsonParseFlagEnum.ParseAll);
189 public Either<GraphVertex, TitanOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
191 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
193 if (logger.isDebugEnabled()) {
194 logger.debug("No vertex in graph for id = {} ", id);
196 return Either.right(TitanOperationStatus.NOT_FOUND);
198 if (graph.isLeft()) {
200 TitanGraph tGraph = graph.left().value();
202 @SuppressWarnings("unchecked")
203 Iterable<TitanVertex> vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
205 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
206 if (iterator.hasNext()) {
207 TitanVertex vertex = iterator.next();
208 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
209 return Either.left(graphVertex);
211 if (logger.isDebugEnabled()) {
212 logger.debug("No vertex in graph for id = {}", id);
214 return Either.right(TitanOperationStatus.NOT_FOUND);
216 } catch (Exception e) {
217 if (logger.isDebugEnabled()) {
218 logger.debug("Failed to get vertex in graph for id {} ", id);
220 return Either.right(TitanGraphClient.handleTitanException(e));
223 if (logger.isDebugEnabled()) {
224 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
226 return Either.right(graph.right().value());
230 private void setVertexProperties(TitanVertex vertex, GraphVertex graphVertex) throws IOException {
232 if (graphVertex.getMetadataProperties() != null) {
233 for (Map.Entry<GraphPropertyEnum, Object> entry : graphVertex.getMetadataProperties().entrySet()) {
234 if (entry.getValue() != null) {
235 vertex.property(entry.getKey().getProperty(), entry.getValue());
239 vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
241 Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
243 String jsonStr = JsonParserUtils.jsonToString(json);
244 vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
247 Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
248 if (jsonMetadata != null) {
249 String jsonMetadataStr = JsonParserUtils.jsonToString(jsonMetadata);
250 vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
254 public void setVertexProperties(Vertex vertex, Map<String, Object> properties) throws IOException {
255 for (Map.Entry<String, Object> entry : properties.entrySet()) {
256 if (entry.getValue() != null) {
257 vertex.property(entry.getKey(), entry.getValue());
262 private GraphVertex createAndFill(TitanVertex vertex, JsonParseFlagEnum parseFlag) {
263 GraphVertex graphVertex = new GraphVertex();
264 graphVertex.setVertex(vertex);
265 parseVertexProperties(graphVertex, parseFlag);
269 public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag ) {
270 TitanVertex vertex = graphVertex.getVertex();
271 Map<GraphPropertyEnum, Object> properties = getVertexProperties(vertex);
272 VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
273 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
274 GraphPropertyEnum key = entry.getKey();
277 graphVertex.setUniqueId((String) entry.getValue());
280 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
283 String type = (String) entry.getValue();
285 graphVertex.setType(ComponentTypeEnum.valueOf(type));
289 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) {
290 String json = (String) entry.getValue();
291 Map<String, ? extends ToscaDataDefinition> jsonObj = JsonParserUtils.parseToJson(json, label.getClassOfJson());
292 graphVertex.setJson(jsonObj);
296 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) {
297 String json = (String) entry.getValue();
298 Map<String, Object> metadatObj = JsonParserUtils.parseToJson(json);
299 graphVertex.setMetadataJson(metadatObj);
303 graphVertex.addMetadataProperty(key, entry.getValue());
309 public TitanOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
310 return createEdge(from.getVertex(), to.getVertex(), label, properties);
313 public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
314 if (logger.isTraceEnabled()) {
315 logger.trace("Try to connect {} with {} label {} properties {}", from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties);
317 if (from == null || to == null) {
318 logger.trace("No Titan vertex for id from {} or id to {}", from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
319 return TitanOperationStatus.NOT_FOUND;
321 Edge edge = from.addEdge(label.name(), to);
322 setEdgeProperties(edge, properties);
323 return TitanOperationStatus.OK;
326 public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
328 Map<GraphPropertyEnum, Object> result = new HashMap<GraphPropertyEnum, Object>();
330 if (element != null && element.keys() != null && element.keys().size() > 0) {
331 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
333 for (Entry<String, Property> entry : propertyMap.entrySet()) {
334 String key = entry.getKey();
335 Object value = entry.getValue().value();
337 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
338 if (valueOf != null) {
339 result.put(valueOf, value);
346 public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
348 Map<EdgePropertyEnum, Object> result = new HashMap<EdgePropertyEnum, Object>();
350 if (element != null && element.keys() != null && element.keys().size() > 0) {
351 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
353 for (Entry<String, Property> entry : propertyMap.entrySet()) {
354 String key = entry.getKey();
355 Object value = entry.getValue().value();
357 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
358 if (valueOf != null) {
359 result.put(valueOf, value);
366 public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) {
368 if (properties != null && !properties.isEmpty()) {
370 Object[] propertyKeyValues = new Object[properties.size() * 2];
372 for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
373 propertyKeyValues[i++] = entry.getKey().getProperty();
374 propertyKeyValues[i++] = entry.getValue();
377 ElementHelper.attachProperties(element, propertyKeyValues);
383 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
384 return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
387 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, JsonParseFlagEnum parseFlag) {
388 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
389 if (graph.isLeft()) {
391 TitanGraph tGraph = graph.left().value();
393 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
395 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
398 if (props != null && !props.isEmpty()) {
399 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
400 query = query.has(entry.getKey().getProperty(), entry.getValue());
403 Iterable<TitanVertex> vertices = query.vertices();
404 if (vertices == null) {
405 return Either.right(TitanOperationStatus.NOT_FOUND);
408 Iterator<TitanVertex> iterator = vertices.iterator();
409 List<GraphVertex> result = new ArrayList<GraphVertex>();
411 while (iterator.hasNext()) {
412 TitanVertex vertex = iterator.next();
414 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
415 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
417 result.add(graphVertex);
419 if (logger.isDebugEnabled()) {
420 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
422 if (result.size() == 0) {
423 return Either.right(TitanOperationStatus.NOT_FOUND);
426 return Either.left(result);
427 } catch (Exception e) {
428 if (logger.isDebugEnabled()) {
429 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
431 return Either.right(TitanGraphClient.handleTitanException(e));
435 if (logger.isDebugEnabled()) {
436 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
438 return Either.right(graph.right().value());
441 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, Map<GraphPropertyEnum, Object> hasNotProps, JsonParseFlagEnum parseFlag) {
442 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
443 if (graph.isLeft()) {
445 TitanGraph tGraph = graph.left().value();
447 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
449 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
452 if (props != null && !props.isEmpty()) {
453 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
454 query = query.has(entry.getKey().getProperty(), entry.getValue());
457 if (hasNotProps != null && !hasNotProps.isEmpty()) {
458 for (Map.Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
459 if(entry.getValue() instanceof List){
460 buildMultipleNegateQueryFromList(entry, query);
462 query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
466 Iterable<TitanVertex> vertices = query.vertices();
467 if (vertices == null) {
468 return Either.right(TitanOperationStatus.NOT_FOUND);
471 Iterator<TitanVertex> iterator = vertices.iterator();
472 List<GraphVertex> result = new ArrayList<GraphVertex>();
474 while (iterator.hasNext()) {
475 TitanVertex vertex = iterator.next();
477 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
478 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
480 result.add(graphVertex);
482 if (logger.isDebugEnabled()) {
483 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
485 if (result.size() == 0) {
486 return Either.right(TitanOperationStatus.NOT_FOUND);
489 return Either.left(result);
490 } catch (Exception e) {
491 if (logger.isDebugEnabled()) {
492 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
494 return Either.right(TitanGraphClient.handleTitanException(e));
498 if (logger.isDebugEnabled()) {
499 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
501 return Either.right(graph.right().value());
507 private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, TitanGraphQuery query){
508 List<Object> negateList = (List<Object>) entry.getValue();
509 for (Object listItem : negateList) {
510 query.hasNot(entry.getKey().getProperty(), listItem);
517 * @param parentVertex
522 public Either<GraphVertex, TitanOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
523 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag);
524 if (childrenVertecies.isRight()) {
525 return Either.right(childrenVertecies.right().value());
527 return Either.left(childrenVertecies.left().value().get(0));
530 public Either<GraphVertex, TitanOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
531 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag);
532 if (childrenVertecies.isRight()) {
533 return Either.right(childrenVertecies.right().value());
535 return Either.left(childrenVertecies.left().value().get(0));
540 * @param parentVertex
545 public Either<List<GraphVertex>, TitanOperationStatus> getChildrenVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
546 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT);
549 public Either<List<GraphVertex>, TitanOperationStatus> getParentVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
550 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN);
553 private Either<List<GraphVertex>, TitanOperationStatus> getAdjacentVerticies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
554 List<GraphVertex> list = new ArrayList<GraphVertex>();
557 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
558 if (graphRes.isRight()) {
559 logger.error("Failed to retrieve graph. status is {}", graphRes);
560 return Either.right(graphRes.right().value());
562 Iterator<Edge> edgesCreatorIterator = parentVertex.getVertex().edges(direction, edgeLabel.name());
563 if (edgesCreatorIterator != null) {
564 while (edgesCreatorIterator.hasNext()) {
565 Edge edge = edgesCreatorIterator.next();
567 if (direction == Direction.IN) {
568 vertex = (TitanVertex) edge.outVertex();
570 vertex = (TitanVertex) edge.inVertex();
572 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
574 list.add(graphVertex);
577 if (true == list.isEmpty()) {
578 return Either.right(TitanOperationStatus.NOT_FOUND);
580 } catch (Exception e) {
581 logger.error("Failed to perform graph operation ", e);
582 Either.right(TitanGraphClient.handleTitanException(e));
585 return Either.left(list);
589 * Searches Edge by received label and criteria
594 * @return found edge or TitanOperationStatus
596 public Either<Edge, TitanOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
598 Either<Edge, TitanOperationStatus> result = null;
599 Edge matchingEdge = null;
600 String notFoundMsg = "No edges in graph for criteria";
602 TitanVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
604 if (properties != null && !properties.isEmpty()) {
605 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
606 query = query.has(entry.getKey().getProperty(), entry.getValue());
610 Iterable<TitanEdge> edges = query.edges();
612 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
613 result = Either.right(TitanOperationStatus.NOT_FOUND);
615 Iterator<TitanEdge> eIter = edges.iterator();
616 if (eIter.hasNext()) {
617 matchingEdge = eIter.next();
619 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
620 result = Either.right(TitanOperationStatus.NOT_FOUND);
623 if (result == null) {
624 result = Either.left(matchingEdge);
626 } catch (Exception e) {
627 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
628 return Either.right(TitanGraphClient.handleTitanException(e));
634 * Deletes Edge by received label and criteria
641 public Either<Edge, TitanOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
642 Either<Edge, TitanOperationStatus> result = null;
644 result = getBelongingEdgeByCriteria(vertex, label, properties);
645 if (result.isLeft()) {
646 Edge edge = result.left().value();
647 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
649 result = Either.left(edge);
651 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
653 } catch (Exception e) {
654 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex.getUniqueId(), e);
655 return Either.right(TitanGraphClient.handleTitanException(e));
660 @SuppressWarnings("unchecked")
662 * Deletes an edge between vertices fromVertex and toVertex according to received label
669 public Either<Edge, TitanOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
670 Either<Edge, TitanOperationStatus> result = null;
672 Iterable<TitanEdge> edges = fromVertex.getVertex().query().labels(label.name()).edges();
673 Iterator<TitanEdge> eIter = edges.iterator();
674 while (eIter.hasNext()) {
675 Edge edge = eIter.next();
676 String currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
677 if (currVertexUniqueId != null && currVertexUniqueId.equals(toVertex.getUniqueId())) {
678 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), fromVertex.getUniqueId(), toVertex.getUniqueId());
680 result = Either.left(edge);
684 if (result == null) {
685 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), fromVertex.getUniqueId(), toVertex.getUniqueId());
686 result = Either.right(TitanOperationStatus.NOT_FOUND);
688 } catch (Exception e) {
689 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), fromVertex.getUniqueId(), toVertex.getUniqueId(), e);
690 return Either.right(TitanGraphClient.handleTitanException(e));
695 public TitanOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
697 Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
699 while (edges.hasNext()) {
700 Edge edge = edges.next();
703 } catch (Exception e) {
704 logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
705 return TitanGraphClient.handleTitanException(e);
707 return TitanOperationStatus.OK;
711 * Updates vertex properties. Note that graphVertex argument should contain updated data
716 public Either<GraphVertex, TitanOperationStatus> updateVertex(GraphVertex graphVertex) {
717 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
719 graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
720 setVertexProperties(graphVertex.getVertex(), graphVertex);
722 } catch (Exception e) {
723 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
724 return Either.right(TitanGraphClient.handleTitanException(e));
726 return Either.left(graphVertex);
730 * Fetches vertices by uniqueId according to received parse flag
732 * @param verticesToGet
735 public Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesByUniqueIdAndParseFlag(Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
737 Either<Map<String, GraphVertex>, TitanOperationStatus> result = null;
738 Map<String, GraphVertex> vertices = new HashMap<>();
739 TitanOperationStatus titatStatus;
740 Either<GraphVertex, TitanOperationStatus> getVertexRes = null;
741 for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
742 if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
743 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
744 } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
745 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue());
747 if (getVertexRes == null) {
748 titatStatus = TitanOperationStatus.ILLEGAL_ARGUMENT;
749 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus);
750 result = Either.right(titatStatus);
752 if (getVertexRes.isRight()) {
753 titatStatus = getVertexRes.right().value();
754 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
755 result = Either.right(titatStatus);
758 vertices.put(entry.getKey(), getVertexRes.left().value());
761 if (result == null) {
762 result = Either.left(vertices);
768 * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
776 public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
777 return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
780 public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
782 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
783 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
784 TitanOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
785 if (result == TitanOperationStatus.OK) {
792 * Replaces previous label of edge with new label
800 public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
802 TitanOperationStatus result = null;
803 Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
804 if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
805 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
806 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
807 result = TitanOperationStatus.NOT_FOUND;
809 if (result == null) {
810 result = replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
816 * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
823 public TitanOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
825 if (!MapUtils.isEmpty(properties)) {
826 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
827 Map<String, Object> jsonMetadataMap = JsonParserUtils.parseToJson(jsonMetadataStr);
828 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
829 vertex.property(property.getKey().getProperty(), property.getValue());
830 jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
832 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.jsonToString(jsonMetadataMap));
834 } catch (Exception e) {
835 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
836 return TitanGraphClient.handleTitanException(e);
838 return TitanOperationStatus.OK;
841 public TitanOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
843 Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
845 while (edges.hasNext()) {
846 Edge edge = edges.next();
848 Direction reverseDirection;
849 if (direction == Direction.IN) {
850 secondVertex = edge.outVertex();
851 reverseDirection = Direction.OUT;
853 secondVertex = edge.inVertex();
854 reverseDirection = Direction.IN;
857 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex());
859 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
860 if (restOfEdges.hasNext() == false) {
861 secondVertex.remove();
862 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId());
865 } catch (Exception e) {
866 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e);
867 return TitanGraphClient.handleTitanException(e);
869 return TitanOperationStatus.OK;
872 public Object getProperty(TitanVertex vertex, String key) {
873 PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key);
874 Object value = vertex.valueOrNull(propertyKey);
878 public Object getProperty(Edge edge, EdgePropertyEnum key) {
881 Property<Object> property = edge.property(key.getProperty());
882 if (property != null) {
883 return property.orElse(null);
885 } catch (Exception e) {
898 public TitanOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
899 TitanOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
900 if ( result != TitanOperationStatus.OK ){
901 logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
904 TitanOperationStatus createRelation;
905 if (direction == Direction.IN ){
906 createRelation = createEdge(vertexB, vertexA, label, null);
908 createRelation = createEdge(vertexA, vertexB, label, null);
910 if (createRelation != TitanOperationStatus.OK) {
911 return createRelation;
913 return TitanOperationStatus.OK;
916 public Either<Edge, TitanOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
917 Either<GraphVertex, TitanOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
918 if(getVertexRes.isRight()){
919 return Either.right(getVertexRes.right().value());
921 return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);