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);
130 public Either<GraphVertex, TitanOperationStatus> getVertexByLabel(VertexTypeEnum label) {
131 return titanClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices()).left().bind(titanVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, titanVertices));
134 private Either<GraphVertex, TitanOperationStatus> getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable<TitanVertex> vertices) {
135 Iterator<TitanVertex> iterator = vertices.iterator();
136 if (iterator.hasNext()) {
137 TitanVertex vertex = iterator.next();
138 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
140 return Either.left(graphVertex);
142 return Either.right(TitanOperationStatus.NOT_FOUND);
153 public Either<GraphVertex, TitanOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) {
155 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
156 if (graph.isLeft()) {
158 TitanGraph tGraph = graph.left().value();
160 @SuppressWarnings("unchecked")
161 Iterable<TitanVertex> vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
163 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
164 if (iterator.hasNext()) {
165 TitanVertex vertex = iterator.next();
166 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
168 return Either.left(graphVertex);
170 if (logger.isDebugEnabled()) {
171 logger.debug("No vertex in graph for key = {} and value = {} label = {}" + name, value, label);
173 return Either.right(TitanOperationStatus.NOT_FOUND);
174 } catch (Exception e) {
175 if (logger.isDebugEnabled()) {
176 logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
178 return Either.right(TitanGraphClient.handleTitanException(e));
182 if (logger.isDebugEnabled()) {
183 logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value());
185 return Either.right(graph.right().value());
194 public Either<GraphVertex, TitanOperationStatus> getVertexById(String id) {
195 return getVertexById(id, JsonParseFlagEnum.ParseAll);
204 public Either<GraphVertex, TitanOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
206 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
208 if (logger.isDebugEnabled()) {
209 logger.debug("No vertex in graph for id = {} ", id);
211 return Either.right(TitanOperationStatus.NOT_FOUND);
213 if (graph.isLeft()) {
215 TitanGraph tGraph = graph.left().value();
217 @SuppressWarnings("unchecked")
218 Iterable<TitanVertex> vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
220 java.util.Iterator<TitanVertex> iterator = vertecies.iterator();
221 if (iterator.hasNext()) {
222 TitanVertex vertex = iterator.next();
223 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
224 return Either.left(graphVertex);
226 if (logger.isDebugEnabled()) {
227 logger.debug("No vertex in graph for id = {}", id);
229 return Either.right(TitanOperationStatus.NOT_FOUND);
231 } catch (Exception e) {
232 if (logger.isDebugEnabled()) {
233 logger.debug("Failed to get vertex in graph for id {} ", id);
235 return Either.right(TitanGraphClient.handleTitanException(e));
238 if (logger.isDebugEnabled()) {
239 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
241 return Either.right(graph.right().value());
245 private void setVertexProperties(TitanVertex vertex, GraphVertex graphVertex) throws IOException {
247 if (graphVertex.getMetadataProperties() != null) {
248 for (Map.Entry<GraphPropertyEnum, Object> entry : graphVertex.getMetadataProperties().entrySet()) {
249 if (entry.getValue() != null) {
250 vertex.property(entry.getKey().getProperty(), entry.getValue());
254 vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
256 Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
258 String jsonStr = JsonParserUtils.toJson(json);
259 vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
262 Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
263 if (jsonMetadata != null) {
264 String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata);
265 vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
269 public void setVertexProperties(Vertex vertex, Map<String, Object> properties) throws IOException {
270 for (Map.Entry<String, Object> entry : properties.entrySet()) {
271 if (entry.getValue() != null) {
272 vertex.property(entry.getKey(), entry.getValue());
277 private GraphVertex createAndFill(TitanVertex vertex, JsonParseFlagEnum parseFlag) {
278 GraphVertex graphVertex = new GraphVertex();
279 graphVertex.setVertex(vertex);
280 parseVertexProperties(graphVertex, parseFlag);
284 public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) {
285 TitanVertex vertex = graphVertex.getVertex();
286 Map<GraphPropertyEnum, Object> properties = getVertexProperties(vertex);
287 VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
288 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
289 GraphPropertyEnum key = entry.getKey();
292 graphVertex.setUniqueId((String) entry.getValue());
295 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
298 String type = (String) entry.getValue();
300 graphVertex.setType(ComponentTypeEnum.valueOf(type));
304 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) {
305 String json = (String) entry.getValue();
306 Map<String, ? extends ToscaDataDefinition> jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson());
307 graphVertex.setJson(jsonObj);
311 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) {
312 String json = (String) entry.getValue();
313 Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
314 graphVertex.setMetadataJson(metadatObj);
318 graphVertex.addMetadataProperty(key, entry.getValue());
324 public TitanOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
325 return createEdge(from.getVertex(), to.getVertex(), label, properties);
328 public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
329 if (logger.isTraceEnabled()) {
330 logger.trace("Try to connect {} with {} label {} properties {}", from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties);
332 if (from == null || to == null) {
333 logger.trace("No Titan vertex for id from {} or id to {}", from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
334 return TitanOperationStatus.NOT_FOUND;
336 Edge edge = from.addEdge(label.name(), to);
337 setEdgeProperties(edge, properties);
338 return TitanOperationStatus.OK;
341 public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
343 Map<GraphPropertyEnum, Object> result = new HashMap<GraphPropertyEnum, Object>();
345 if (element != null && element.keys() != null && element.keys().size() > 0) {
346 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
348 for (Entry<String, Property> entry : propertyMap.entrySet()) {
349 String key = entry.getKey();
350 Object value = entry.getValue().value();
352 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
353 if (valueOf != null) {
354 result.put(valueOf, value);
361 public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
363 Map<EdgePropertyEnum, Object> result = new HashMap<EdgePropertyEnum, Object>();
365 if (element != null && element.keys() != null && element.keys().size() > 0) {
366 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
368 for (Entry<String, Property> entry : propertyMap.entrySet()) {
369 String key = entry.getKey();
370 Object value = entry.getValue().value();
372 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
373 if (valueOf != null) {
374 result.put(valueOf, value);
381 public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) {
383 if (properties != null && !properties.isEmpty()) {
385 Object[] propertyKeyValues = new Object[properties.size() * 2];
387 for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
388 propertyKeyValues[i++] = entry.getKey().getProperty();
389 propertyKeyValues[i++] = entry.getValue();
392 ElementHelper.attachProperties(element, propertyKeyValues);
398 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
399 return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
402 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, JsonParseFlagEnum parseFlag) {
403 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
404 if (graph.isLeft()) {
406 TitanGraph tGraph = graph.left().value();
408 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
410 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
413 if (props != null && !props.isEmpty()) {
414 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
415 query = query.has(entry.getKey().getProperty(), entry.getValue());
418 Iterable<TitanVertex> vertices = query.vertices();
419 if (vertices == null) {
420 return Either.right(TitanOperationStatus.NOT_FOUND);
423 Iterator<TitanVertex> iterator = vertices.iterator();
424 List<GraphVertex> result = new ArrayList<GraphVertex>();
426 while (iterator.hasNext()) {
427 TitanVertex vertex = iterator.next();
429 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
430 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
432 result.add(graphVertex);
434 if (logger.isDebugEnabled()) {
435 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
437 if (result.size() == 0) {
438 return Either.right(TitanOperationStatus.NOT_FOUND);
441 return Either.left(result);
442 } catch (Exception e) {
443 if (logger.isDebugEnabled()) {
444 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
446 return Either.right(TitanGraphClient.handleTitanException(e));
450 if (logger.isDebugEnabled()) {
451 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
453 return Either.right(graph.right().value());
457 public Either<List<GraphVertex>, TitanOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, Map<GraphPropertyEnum, Object> hasNotProps, JsonParseFlagEnum parseFlag) {
458 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
459 if (graph.isLeft()) {
461 TitanGraph tGraph = graph.left().value();
463 TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query();
465 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
468 if (props != null && !props.isEmpty()) {
469 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
470 query = query.has(entry.getKey().getProperty(), entry.getValue());
473 if (hasNotProps != null && !hasNotProps.isEmpty()) {
474 for (Map.Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
475 if (entry.getValue() instanceof List) {
476 buildMultipleNegateQueryFromList(entry, query);
478 query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
482 Iterable<TitanVertex> vertices = query.vertices();
483 if (vertices == null) {
484 return Either.right(TitanOperationStatus.NOT_FOUND);
487 Iterator<TitanVertex> iterator = vertices.iterator();
488 List<GraphVertex> result = new ArrayList<GraphVertex>();
490 while (iterator.hasNext()) {
491 TitanVertex vertex = iterator.next();
493 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
494 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
496 result.add(graphVertex);
498 if (logger.isDebugEnabled()) {
499 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
501 if (result.size() == 0) {
502 return Either.right(TitanOperationStatus.NOT_FOUND);
505 return Either.left(result);
506 } catch (Exception e) {
507 if (logger.isDebugEnabled()) {
508 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
510 return Either.right(TitanGraphClient.handleTitanException(e));
514 if (logger.isDebugEnabled()) {
515 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
517 return Either.right(graph.right().value());
521 public Either<Iterator<Vertex>, TitanOperationStatus> getCatalogVerticies() {
522 Either<TitanGraph, TitanOperationStatus> graph = titanClient.getGraph();
523 if (graph.isLeft()) {
525 TitanGraph tGraph = graph.left().value();
527 Iterable<TitanVertex> vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), VertexTypeEnum.CATALOG_ROOT.getName()).vertices();
528 if (vCatalogIter == null) {
529 logger.debug("Failed to fetch catalog vertex");
530 return Either.right(TitanOperationStatus.GENERAL_ERROR);
532 TitanVertex catalogV = vCatalogIter.iterator().next();
533 if (catalogV == null) {
534 logger.debug("Failed to fetch catalog vertex");
535 return Either.right(TitanOperationStatus.GENERAL_ERROR);
537 Iterator<Vertex> vertices = catalogV.vertices(Direction.OUT, EdgeLabelEnum.CATALOG_ELEMENT.name());
539 return Either.left(vertices);
540 } catch (Exception e) {
541 if (logger.isDebugEnabled()) {
542 logger.debug("Failed get by criteria: ", e);
544 return Either.right(TitanGraphClient.handleTitanException(e));
548 if (logger.isDebugEnabled()) {
549 logger.debug("Failed get by criteria : ", graph.right().value());
551 return Either.right(graph.right().value());
555 private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, TitanGraphQuery query) {
556 List<Object> negateList = (List<Object>) entry.getValue();
557 for (Object listItem : negateList) {
558 query.hasNot(entry.getKey().getProperty(), listItem);
564 * @param parentVertex
569 public Either<GraphVertex, TitanOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
570 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag);
571 if (childrenVertecies.isRight()) {
572 return Either.right(childrenVertecies.right().value());
574 return Either.left(childrenVertecies.left().value().get(0));
579 * @param parentVertex
584 public Either<Vertex, TitanOperationStatus> getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
585 Either<List<Vertex>, TitanOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag);
586 if (childrenVertecies.isRight()) {
587 return Either.right(childrenVertecies.right().value());
589 return Either.left(childrenVertecies.left().value().get(0));
592 public Either<GraphVertex, TitanOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
593 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag);
594 if (childrenVertecies.isRight()) {
595 return Either.right(childrenVertecies.right().value());
597 return Either.left(childrenVertecies.left().value().get(0));
600 public Either<Vertex, TitanOperationStatus> getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
601 Either<List<Vertex>, TitanOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag);
602 if (childrenVertecies.isRight()) {
603 return Either.right(childrenVertecies.right().value());
605 return Either.left(childrenVertecies.left().value().get(0));
610 * @param parentVertex
615 public Either<List<GraphVertex>, TitanOperationStatus> getChildrenVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
616 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT);
619 public Either<List<GraphVertex>, TitanOperationStatus> getParentVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
620 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN);
623 public Either<List<Vertex>, TitanOperationStatus> getParentVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
624 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN);
627 private Either<List<Vertex>, TitanOperationStatus> getAdjacentVerticies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
628 List<Vertex> list = new ArrayList<>();
630 Either<TitanGraph, TitanOperationStatus> graphRes = titanClient.getGraph();
631 if (graphRes.isRight()) {
632 logger.error("Failed to retrieve graph. status is {}", graphRes);
633 return Either.right(graphRes.right().value());
635 Iterator<Edge> edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name());
636 if (edgesCreatorIterator != null) {
637 while (edgesCreatorIterator.hasNext()) {
638 Edge edge = edgesCreatorIterator.next();
640 if (direction == Direction.IN) {
641 vertex = (TitanVertex) edge.outVertex();
643 vertex = (TitanVertex) edge.inVertex();
645 // GraphVertex graphVertex = createAndFill(vertex, parseFlag);
650 if (true == list.isEmpty()) {
651 return Either.right(TitanOperationStatus.NOT_FOUND);
653 } catch (Exception e) {
654 logger.error("Failed to perform graph operation ", e);
655 Either.right(TitanGraphClient.handleTitanException(e));
658 return Either.left(list);
663 * @param parentVertex
668 public Either<List<Vertex>, TitanOperationStatus> getChildrenVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
669 return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT);
672 private Either<List<GraphVertex>, TitanOperationStatus> getAdjacentVerticies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
673 List<GraphVertex> list = new ArrayList<GraphVertex>();
675 Either<List<Vertex>, TitanOperationStatus> adjacentVerticies = getAdjacentVerticies(parentVertex.getVertex(), edgeLabel, parseFlag, direction);
676 if (adjacentVerticies.isRight()) {
677 return Either.right(adjacentVerticies.right().value());
679 adjacentVerticies.left().value().stream().forEach(vertex -> {
680 list.add(createAndFill((TitanVertex) vertex, parseFlag));
683 return Either.left(list);
687 * Searches Edge by received label and criteria
692 * @return found edge or TitanOperationStatus
694 public Either<Edge, TitanOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
696 Either<Edge, TitanOperationStatus> result = null;
697 Edge matchingEdge = null;
698 String notFoundMsg = "No edges in graph for criteria";
700 TitanVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
702 if (properties != null && !properties.isEmpty()) {
703 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
704 query = query.has(entry.getKey().getProperty(), entry.getValue());
708 Iterable<TitanEdge> edges = query.edges();
710 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
711 result = Either.right(TitanOperationStatus.NOT_FOUND);
713 Iterator<TitanEdge> eIter = edges.iterator();
714 if (eIter.hasNext()) {
715 matchingEdge = eIter.next();
717 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
718 result = Either.right(TitanOperationStatus.NOT_FOUND);
721 if (result == null) {
722 result = Either.left(matchingEdge);
724 } catch (Exception e) {
725 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
726 return Either.right(TitanGraphClient.handleTitanException(e));
732 * Deletes Edge by received label and criteria
739 public Either<Edge, TitanOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
740 Either<Edge, TitanOperationStatus> result = null;
742 result = getBelongingEdgeByCriteria(vertex, label, properties);
743 if (result.isLeft()) {
744 Edge edge = result.left().value();
745 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
747 result = Either.left(edge);
749 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
751 } catch (Exception e) {
752 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex.getUniqueId(), e);
753 return Either.right(TitanGraphClient.handleTitanException(e));
758 @SuppressWarnings("unchecked")
760 * Deletes an edge between vertices fromVertex and toVertex according to received label
768 public Either<Edge, TitanOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
769 return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId());
772 public Either<Edge, TitanOperationStatus> deleteEdge(TitanVertex fromVertex, TitanVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo) {
773 Either<Edge, TitanOperationStatus> result = null;
775 Iterable<TitanEdge> edges = fromVertex.query().labels(label.name()).edges();
776 Iterator<TitanEdge> eIter = edges.iterator();
777 while (eIter.hasNext()) {
778 Edge edge = eIter.next();
779 String currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
780 if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) {
781 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
783 result = Either.left(edge);
787 if (result == null) {
788 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
789 result = Either.right(TitanOperationStatus.NOT_FOUND);
791 } catch (Exception e) {
792 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e);
793 return Either.right(TitanGraphClient.handleTitanException(e));
798 public TitanOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
800 Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
802 while (edges.hasNext()) {
803 Edge edge = edges.next();
806 } catch (Exception e) {
807 logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
808 return TitanGraphClient.handleTitanException(e);
810 return TitanOperationStatus.OK;
814 * Updates vertex properties. Note that graphVertex argument should contain updated data
819 public Either<GraphVertex, TitanOperationStatus> updateVertex(GraphVertex graphVertex) {
820 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
822 graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
823 setVertexProperties(graphVertex.getVertex(), graphVertex);
825 } catch (Exception e) {
826 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
827 return Either.right(TitanGraphClient.handleTitanException(e));
829 return Either.left(graphVertex);
833 * Fetches vertices by uniqueId according to received parse flag
835 * @param verticesToGet
838 public Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesByUniqueIdAndParseFlag(Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
840 Either<Map<String, GraphVertex>, TitanOperationStatus> result = null;
841 Map<String, GraphVertex> vertices = new HashMap<>();
842 TitanOperationStatus titatStatus;
843 Either<GraphVertex, TitanOperationStatus> getVertexRes = null;
844 for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
845 if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
846 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
847 } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
848 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue());
850 if (getVertexRes == null) {
851 titatStatus = TitanOperationStatus.ILLEGAL_ARGUMENT;
852 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus);
853 result = Either.right(titatStatus);
855 if (getVertexRes.isRight()) {
856 titatStatus = getVertexRes.right().value();
857 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
858 result = Either.right(titatStatus);
861 vertices.put(entry.getKey(), getVertexRes.left().value());
864 if (result == null) {
865 result = Either.left(vertices);
871 * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
879 public TitanOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
880 return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
883 public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
885 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
886 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
887 TitanOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
888 if (result == TitanOperationStatus.OK) {
895 * Replaces previous label of edge with new label
903 public TitanOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
905 TitanOperationStatus result = null;
906 Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
907 if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
908 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
909 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
910 result = TitanOperationStatus.NOT_FOUND;
912 if (result == null) {
913 result = replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
919 * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
926 public TitanOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
928 if (!MapUtils.isEmpty(properties)) {
929 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
930 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr);
931 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
932 vertex.property(property.getKey().getProperty(), property.getValue());
933 jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
935 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
937 } catch (Exception e) {
938 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
939 return TitanGraphClient.handleTitanException(e);
941 return TitanOperationStatus.OK;
944 public TitanOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
946 Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
948 while (edges.hasNext()) {
949 Edge edge = edges.next();
951 Direction reverseDirection;
952 if (direction == Direction.IN) {
953 secondVertex = edge.outVertex();
954 reverseDirection = Direction.OUT;
956 secondVertex = edge.inVertex();
957 reverseDirection = Direction.IN;
960 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex());
962 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
963 if (restOfEdges.hasNext() == false) {
964 secondVertex.remove();
965 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId());
968 } catch (Exception e) {
969 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e);
970 return TitanGraphClient.handleTitanException(e);
972 return TitanOperationStatus.OK;
975 public Object getProperty(TitanVertex vertex, String key) {
976 PropertyKey propertyKey = titanClient.getGraph().left().value().getPropertyKey(key);
977 Object value = vertex.valueOrNull(propertyKey);
981 public Object getProperty(Edge edge, EdgePropertyEnum key) {
984 Property<Object> property = edge.property(key.getProperty());
985 if (property != null) {
986 return property.orElse(null);
988 } catch (Exception e) {
1002 public TitanOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
1003 TitanOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
1004 if (result != TitanOperationStatus.OK) {
1005 logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
1008 TitanOperationStatus createRelation;
1009 if (direction == Direction.IN) {
1010 createRelation = createEdge(vertexB, vertexA, label, null);
1012 createRelation = createEdge(vertexA, vertexB, label, null);
1014 if (createRelation != TitanOperationStatus.OK) {
1015 return createRelation;
1017 return TitanOperationStatus.OK;
1020 public Either<Edge, TitanOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
1021 Either<GraphVertex, TitanOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
1022 if (getVertexRes.isRight()) {
1023 return Either.right(getVertexRes.right().value());
1025 return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);