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 org.janusgraph.core.*;
24 import fj.data.Either;
25 import org.apache.commons.collections.MapUtils;
26 import org.apache.commons.lang3.tuple.ImmutablePair;
27 import org.apache.tinkerpop.gremlin.structure.*;
28 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
29 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient;
30 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
31 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
32 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
34 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
35 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
36 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
37 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
38 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
39 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
40 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
41 import org.openecomp.sdc.common.log.wrappers.Logger;
42 import org.springframework.beans.factory.annotation.Qualifier;
44 import java.io.IOException;
46 import java.util.Map.Entry;
48 import static org.apache.commons.collections.CollectionUtils.isEmpty;
51 public class JanusGraphDao {
52 JanusGraphClient janusGraphClient;
54 private static Logger logger = Logger.getLogger(JanusGraphDao.class.getName());
56 public JanusGraphDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) {
57 this.janusGraphClient = janusGraphClient;
58 logger.info("** JanusGraphDao created");
61 public JanusGraphOperationStatus commit() {
62 logger.debug("#commit - The operation succeeded. Doing commit...");
63 return janusGraphClient.commit();
66 public JanusGraphOperationStatus rollback() {
67 logger.debug("#rollback - The operation failed. Doing rollback...");
68 return janusGraphClient.rollback();
71 public Either<JanusGraph, JanusGraphOperationStatus> getGraph() {
72 return janusGraphClient.getGraph();
80 public Either<GraphVertex, JanusGraphOperationStatus> createVertex(GraphVertex graphVertex) {
81 logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId());
82 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
85 JanusGraph tGraph = graph.left().value();
87 JanusGraphVertex vertex = tGraph.addVertex();
89 setVertexProperties(vertex, graphVertex);
91 graphVertex.setVertex(vertex);
93 return Either.left(graphVertex);
95 } catch (Exception e) {
96 logger.debug("Failed to create Node for ID [{}]", graphVertex.getUniqueId(), e);
97 return Either.right(JanusGraphClient.handleJanusGraphException(e));
100 logger.debug("Failed to create vertex for ID [{}] {}", graphVertex.getUniqueId(), graph.right().value());
101 return Either.right(graph.right().value());
112 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) {
113 return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll);
116 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByLabel(VertexTypeEnum label) {
117 return janusGraphClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices()).left().bind(janusGraphVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, janusGraphVertices));
120 private Either<GraphVertex, JanusGraphOperationStatus> getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable<JanusGraphVertex> vertices) {
121 Iterator<JanusGraphVertex> iterator = vertices.iterator();
122 if (iterator.hasNext()) {
123 JanusGraphVertex vertex = iterator.next();
124 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
126 return Either.left(graphVertex);
128 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
139 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) {
141 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
142 if (graph.isLeft()) {
144 JanusGraph tGraph = graph.left().value();
146 @SuppressWarnings("unchecked")
147 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
149 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
150 if (iterator.hasNext()) {
151 JanusGraphVertex vertex = iterator.next();
152 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
154 return Either.left(graphVertex);
156 if (logger.isDebugEnabled()) {
157 logger.debug("No vertex in graph for key = {} and value = {} label = {}", name, value, label);
159 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
160 } catch (Exception e) {
161 if (logger.isDebugEnabled()) {
162 logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
164 return Either.right(JanusGraphClient.handleJanusGraphException(e));
168 if (logger.isDebugEnabled()) {
169 logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value());
171 return Either.right(graph.right().value());
180 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id) {
181 return getVertexById(id, JsonParseFlagEnum.ParseAll);
190 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
192 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
194 if (logger.isDebugEnabled()) {
195 logger.debug("No vertex in graph for id = {} ", id);
197 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
199 if (graph.isLeft()) {
201 JanusGraph tGraph = graph.left().value();
203 @SuppressWarnings("unchecked")
204 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
206 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
207 if (iterator.hasNext()) {
208 JanusGraphVertex vertex = iterator.next();
209 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
210 return Either.left(graphVertex);
212 if (logger.isDebugEnabled()) {
213 logger.debug("No vertex in graph for id = {}", id);
215 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
217 } catch (Exception e) {
218 if (logger.isDebugEnabled()) {
219 logger.debug("Failed to get vertex in graph for id {} ", id);
221 return Either.right(JanusGraphClient.handleJanusGraphException(e));
224 if (logger.isDebugEnabled()) {
225 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
227 return Either.right(graph.right().value());
231 private void setVertexProperties(JanusGraphVertex vertex, GraphVertex graphVertex) throws IOException {
233 if (graphVertex.getMetadataProperties() != null) {
234 for (Map.Entry<GraphPropertyEnum, Object> entry : graphVertex.getMetadataProperties().entrySet()) {
235 if (entry.getValue() != null) {
236 vertex.property(entry.getKey().getProperty(), entry.getValue());
240 vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
242 Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
244 String jsonStr = JsonParserUtils.toJson(json);
245 vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
248 Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
249 if (jsonMetadata != null) {
250 String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata);
251 vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
255 public void setVertexProperties(Vertex vertex, Map<String, Object> properties) throws IOException {
256 for (Map.Entry<String, Object> entry : properties.entrySet()) {
257 if (entry.getValue() != null) {
258 vertex.property(entry.getKey(), entry.getValue());
263 private GraphVertex createAndFill(JanusGraphVertex vertex, JsonParseFlagEnum parseFlag) {
264 GraphVertex graphVertex = new GraphVertex();
265 graphVertex.setVertex(vertex);
266 parseVertexProperties(graphVertex, parseFlag);
270 public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) {
271 JanusGraphVertex vertex = graphVertex.getVertex();
272 Map<GraphPropertyEnum, Object> properties = getVertexProperties(vertex);
273 VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
274 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
275 GraphPropertyEnum key = entry.getKey();
278 graphVertex.setUniqueId((String) entry.getValue());
281 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
284 String type = (String) entry.getValue();
286 graphVertex.setType(ComponentTypeEnum.valueOf(type));
290 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) {
291 String json = (String) entry.getValue();
292 Map<String, ? extends ToscaDataDefinition> jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson());
293 graphVertex.setJson(jsonObj);
297 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) {
298 String json = (String) entry.getValue();
299 Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
300 graphVertex.setMetadataJson(metadatObj);
304 graphVertex.addMetadataProperty(key, entry.getValue());
310 public JanusGraphOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
311 return createEdge(from.getVertex(), to.getVertex(), label, properties);
314 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
315 if (logger.isTraceEnabled()) {
316 logger.trace("Try to connect {} with {} label {} properties {}",
317 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
318 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties);
320 if (from == null || to == null) {
321 logger.trace("No JanusGraph vertex for id from {} or id to {}",
322 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
323 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
324 return JanusGraphOperationStatus.NOT_FOUND;
326 Edge edge = from.addEdge(label.name(), to);
327 JanusGraphOperationStatus status;
329 setEdgeProperties(edge, properties);
330 status = JanusGraphOperationStatus.OK;
331 } catch (IOException e) {
332 logger.debug("Failed to set properties on edge properties [{}]", properties, e);
333 status = JanusGraphOperationStatus.GENERAL_ERROR;
338 public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
340 Map<GraphPropertyEnum, Object> result = new HashMap<>();
342 if (element != null && element.keys() != null && element.keys().size() > 0) {
343 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
345 for (Entry<String, Property> entry : propertyMap.entrySet()) {
346 String key = entry.getKey();
347 Object value = entry.getValue().value();
349 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
350 if (valueOf != null) {
351 result.put(valueOf, value);
354 // add print to properties that can't be converted by enum
359 public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
361 Map<EdgePropertyEnum, Object> result = new HashMap<>();
363 if (element != null && element.keys() != null && element.keys().size() > 0) {
364 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
366 for (Entry<String, Property> entry : propertyMap.entrySet()) {
367 String key = entry.getKey();
368 Object value = entry.getValue().value();
370 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
371 if (valueOf != null) {
372 if (valueOf == EdgePropertyEnum.INSTANCES) {
373 List<String> list = JsonParserUtils.toList((String) value, String.class);
374 result.put(valueOf, list);
376 result.put(valueOf, value);
384 public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) throws IOException {
386 if (properties != null && !properties.isEmpty()) {
388 Object[] propertyKeyValues = new Object[properties.size() * 2];
390 for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
391 propertyKeyValues[i++] = entry.getKey().getProperty();
392 Object value = entry.getValue();
393 if (entry.getKey() == EdgePropertyEnum.INSTANCES) {
394 String jsonStr = JsonParserUtils.toJson(value);
395 propertyKeyValues[i++] = jsonStr;
397 propertyKeyValues[i++] = entry.getValue();
400 ElementHelper.attachProperties(element, propertyKeyValues);
404 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
405 return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
408 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, JsonParseFlagEnum parseFlag) {
409 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
410 if (graph.isLeft()) {
412 JanusGraph tGraph = graph.left().value();
414 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
416 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
419 if (props != null && !props.isEmpty()) {
420 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
421 query = query.has(entry.getKey().getProperty(), entry.getValue());
424 Iterable<JanusGraphVertex> vertices = query.vertices();
425 if (vertices == null) {
426 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
429 Iterator<JanusGraphVertex> iterator = vertices.iterator();
430 List<GraphVertex> result = new ArrayList<>();
432 while (iterator.hasNext()) {
433 JanusGraphVertex vertex = iterator.next();
435 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
436 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
438 result.add(graphVertex);
440 if (logger.isDebugEnabled()) {
441 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
443 if (result.size() == 0) {
444 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
447 return Either.left(result);
448 } catch (Exception e) {
449 if (logger.isDebugEnabled()) {
450 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
452 return Either.right(JanusGraphClient.handleJanusGraphException(e));
456 if (logger.isDebugEnabled()) {
457 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
459 return Either.right(graph.right().value());
463 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, Map<GraphPropertyEnum, Object> hasNotProps, JsonParseFlagEnum parseFlag) {
464 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
465 if (graph.isLeft()) {
467 JanusGraph tGraph = graph.left().value();
469 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
471 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
474 if (props != null && !props.isEmpty()) {
475 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
476 query = query.has(entry.getKey().getProperty(), entry.getValue());
479 if (hasNotProps != null && !hasNotProps.isEmpty()) {
480 for (Map.Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
481 if (entry.getValue() instanceof List) {
482 buildMultipleNegateQueryFromList(entry, query);
484 query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
488 Iterable<JanusGraphVertex> vertices = query.vertices();
489 if (vertices == null) {
490 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
493 Iterator<JanusGraphVertex> iterator = vertices.iterator();
494 List<GraphVertex> result = new ArrayList<>();
496 while (iterator.hasNext()) {
497 JanusGraphVertex vertex = iterator.next();
499 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
500 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
502 result.add(graphVertex);
504 if (logger.isDebugEnabled()) {
505 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
507 if (result.size() == 0) {
508 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
511 return Either.left(result);
512 } catch (Exception e) {
513 if (logger.isDebugEnabled()) {
514 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
516 return Either.right(JanusGraphClient.handleJanusGraphException(e));
520 if (logger.isDebugEnabled()) {
521 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
523 return Either.right(graph.right().value());
527 public Either<Iterator<Vertex>, JanusGraphOperationStatus> getCatalogOrArchiveVerticies(boolean isCatalog) {
528 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
529 if (graph.isLeft()) {
531 JanusGraph tGraph = graph.left().value();
533 String name = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName();
534 Iterable<JanusGraphVertex> vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), name).vertices();
535 if (vCatalogIter == null) {
536 logger.debug("Failed to fetch catalog vertex");
537 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
539 JanusGraphVertex catalogV = vCatalogIter.iterator().next();
540 if (catalogV == null) {
541 logger.debug("Failed to fetch catalog vertex");
542 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
544 String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name();
545 Iterator<Vertex> vertices = catalogV.vertices(Direction.OUT, edgeLabel);
547 return Either.left(vertices);
548 } catch (Exception e) {
549 if (logger.isDebugEnabled()) {
550 logger.debug("Failed get by criteria: ", e);
552 return Either.right(JanusGraphClient.handleJanusGraphException(e));
556 if (logger.isDebugEnabled()) {
557 logger.debug("Failed get by criteria : ", graph.right().value());
559 return Either.right(graph.right().value());
563 private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, JanusGraphQuery query) {
564 List<Object> negateList = (List<Object>) entry.getValue();
565 for (Object listItem : negateList) {
566 query.hasNot(entry.getKey().getProperty(), listItem);
572 * @param parentVertex
577 public Either<GraphVertex, JanusGraphOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
578 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertices(parentVertex, edgeLabel, parseFlag);
579 if (childrenVertecies.isRight()) {
580 return Either.right(childrenVertecies.right().value());
582 return Either.left(childrenVertecies.left().value().get(0));
587 * @param parentVertex
592 public Either<Vertex, JanusGraphOperationStatus> getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
593 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertices(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<GraphVertex, JanusGraphOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
601 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertices(parentVertex, edgeLabel, parseFlag);
602 if (childrenVertecies.isRight()) {
603 return Either.right(childrenVertecies.right().value());
605 if (isEmpty(childrenVertecies.left().value())){
606 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
608 return Either.left(childrenVertecies.left().value().get(0));
611 public Either<Vertex, JanusGraphOperationStatus> getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
612 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertices(parentVertex, edgeLabel, parseFlag);
613 if (childrenVertecies.isRight() ) {
614 return Either.right(childrenVertecies.right().value());
616 if (isEmpty(childrenVertecies.left().value())){
617 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
619 return Either.left(childrenVertecies.left().value().get(0));
624 * @param parentVertex
629 public Either<List<GraphVertex>, JanusGraphOperationStatus> getChildrenVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
630 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.OUT);
633 public Either<List<GraphVertex>, JanusGraphOperationStatus> getParentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
634 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.IN);
637 public Either<List<Vertex>, JanusGraphOperationStatus> getParentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
638 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.IN);
641 private Either<List<Vertex>, JanusGraphOperationStatus> getAdjacentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
642 List<Vertex> list = new ArrayList<>();
644 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
645 if (graphRes.isRight()) {
646 logger.error("Failed to retrieve graph. status is {}", graphRes);
647 return Either.right(graphRes.right().value());
649 Iterator<Edge> edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name());
650 if (edgesCreatorIterator != null) {
651 while (edgesCreatorIterator.hasNext()) {
652 Edge edge = edgesCreatorIterator.next();
653 JanusGraphVertex vertex;
654 if (direction == Direction.IN) {
655 vertex = (JanusGraphVertex) edge.outVertex();
657 vertex = (JanusGraphVertex) edge.inVertex();
659 // GraphVertex graphVertex = createAndFill(vertex, parseFlag);
664 if (list.isEmpty()) {
665 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
667 } catch (Exception e) {
668 logger.error("Failed to perform graph operation ", e);
669 Either.right(JanusGraphClient.handleJanusGraphException(e));
672 return Either.left(list);
677 * @param parentVertex
682 public Either<List<Vertex>, JanusGraphOperationStatus> getChildrenVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
683 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.OUT);
686 private Either<List<GraphVertex>, JanusGraphOperationStatus> getAdjacentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
687 List<GraphVertex> list = new ArrayList<>();
689 Either<List<Vertex>, JanusGraphOperationStatus> adjacentVerticies = getAdjacentVertices(parentVertex.getVertex(), edgeLabel, parseFlag, direction);
690 if (adjacentVerticies.isRight()) {
691 return Either.right(adjacentVerticies.right().value());
693 adjacentVerticies.left().value().stream().forEach(vertex -> {
694 list.add(createAndFill((JanusGraphVertex) vertex, parseFlag));
697 return Either.left(list);
701 * Searches Edge by received label and criteria
706 * @return found edge or JanusGraphOperationStatus
708 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
710 Either<Edge, JanusGraphOperationStatus> result = null;
711 Edge matchingEdge = null;
712 String notFoundMsg = "No edges in graph for criteria";
714 JanusGraphVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
716 if (properties != null && !properties.isEmpty()) {
717 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
718 query = query.has(entry.getKey().getProperty(), entry.getValue());
722 Iterable<JanusGraphEdge> edges = query.edges();
724 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
725 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
727 Iterator<JanusGraphEdge> eIter = edges.iterator();
728 if (eIter.hasNext()) {
729 matchingEdge = eIter.next();
731 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
732 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
735 if (result == null) {
736 result = Either.left(matchingEdge);
738 } catch (Exception e) {
739 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
740 return Either.right(JanusGraphClient.handleJanusGraphException(e));
745 public Either<Edge, JanusGraphOperationStatus> getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
746 Either<Edge, JanusGraphOperationStatus> result = null;
747 Edge matchingEdge = null;
748 String notFoundMsg = "No edges in graph for criteria";
751 Iterator<Edge> edges = vertex.getVertex().edges(Direction.OUT, label.name());
752 while (edges.hasNext()) {
753 matchingEdge = edges.next();
754 Vertex childV = matchingEdge.inVertex();
755 Map<GraphPropertyEnum, Object> vertexProperties = getVertexProperties(childV);
756 Optional<Entry<GraphPropertyEnum, Object>> findNotMatch = properties.entrySet().stream().filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst();
757 if (!findNotMatch.isPresent()) {
758 result = Either.left(matchingEdge);
761 if (result == null) {
763 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
764 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
766 } catch (Exception e) {
767 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
768 return Either.right(JanusGraphClient.handleJanusGraphException(e));
774 * Deletes Edge by received label and criteria
781 public Either<Edge, JanusGraphOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
782 Either<Edge, JanusGraphOperationStatus> result = null;
784 result = getBelongingEdgeByCriteria(vertex, label, properties);
785 if (result.isLeft()) {
786 Edge edge = result.left().value();
787 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
789 result = Either.left(edge);
791 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
793 } catch (Exception e) {
794 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex == null ? "NULL" : vertex.getUniqueId(), e);
795 return Either.right(JanusGraphClient.handleJanusGraphException(e));
800 @SuppressWarnings("unchecked")
802 * Deletes an edge between vertices fromVertex and toVertex according to received label
810 public Either<Edge, JanusGraphOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
811 return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false);
814 public Either<Edge, JanusGraphOperationStatus> deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
815 return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true);
818 public Either<Edge, JanusGraphOperationStatus> deleteEdge(JanusGraphVertex fromVertex, JanusGraphVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) {
819 Either<Edge, JanusGraphOperationStatus> result = null;
820 Vertex problemV = null;
822 Iterable<JanusGraphEdge> edges = fromVertex.query().labels(label.name()).edges();
823 Iterator<JanusGraphEdge> eIter = edges.iterator();
824 while (eIter.hasNext()) {
825 Edge edge = eIter.next();
826 problemV = edge.inVertex();
827 String currVertexUniqueId = null;
829 currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
830 }catch (Exception e){
831 // AutoHealing procedure
832 logger.info( "Corrupted vertex and edge were found and deleted {}",e);
833 if ( problemV != null ) {
834 Map<GraphPropertyEnum, Object> props = getVertexProperties(problemV);
835 logger.debug( "problematic Vertex properties:");
836 logger.debug( "props size: {}", props.size());
837 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
838 logger.debug( "{}{}",entry.getKey() + ":" + entry.getValue());
840 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertices = getChildrenVertices(problemV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
841 if(childrenVertices.isLeft()){
842 childrenVertices.left().value().size();
843 logger.debug( "number of children that problematic Vertex has: {}", props.size());
847 }catch (Exception e1){
848 logger.debug( "failed to remove problematic edge. {}", e1);
852 }catch (Exception e2){
853 logger.debug( "failed to remove problematic vertex . {}", e2);
859 if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) {
860 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
862 result = Either.left(edge);
868 if (result == null) {
869 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
870 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
872 } catch (Exception e) {
874 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e);
875 return Either.right(JanusGraphClient.handleJanusGraphException(e));
880 public JanusGraphOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
882 Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
884 while (edges.hasNext()) {
885 Edge edge = edges.next();
888 } catch (Exception e) {
889 logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
890 return JanusGraphClient.handleJanusGraphException(e);
892 return JanusGraphOperationStatus.OK;
896 * Updates vertex properties. Note that graphVertex argument should contain updated data
901 public Either<GraphVertex, JanusGraphOperationStatus> updateVertex(GraphVertex graphVertex) {
902 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
904 graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
905 setVertexProperties(graphVertex.getVertex(), graphVertex);
907 } catch (Exception e) {
908 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
909 return Either.right(JanusGraphClient.handleJanusGraphException(e));
911 return Either.left(graphVertex);
915 * Fetches vertices by uniqueId according to received parse flag
917 * @param verticesToGet
920 public Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesByUniqueIdAndParseFlag(Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
922 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> result = null;
923 Map<String, GraphVertex> vertices = new HashMap<>();
924 JanusGraphOperationStatus titatStatus;
925 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = null;
926 for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
927 if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
928 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
929 } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
930 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue());
932 if (getVertexRes == null) {
933 titatStatus = JanusGraphOperationStatus.ILLEGAL_ARGUMENT;
934 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus);
935 return Either.right(titatStatus);
937 if (getVertexRes.isRight()) {
938 titatStatus = getVertexRes.right().value();
939 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
940 result = Either.right(titatStatus);
943 vertices.put(entry.getKey(), getVertexRes.left().value());
946 if (result == null) {
947 result = Either.left(vertices);
953 * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
961 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
962 return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
965 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
966 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex!=null ? fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL",
967 toVertex!=null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL");
969 JanusGraphOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
970 if (result == JanusGraphOperationStatus.OK) {
977 * Replaces previous label of edge with new label
985 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel,
986 EdgeLabelEnum newLabel) {
988 Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
989 if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
990 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
991 "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel,
992 fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
993 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
994 return JanusGraphOperationStatus.NOT_FOUND;
996 return replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
1001 * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
1008 public JanusGraphOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
1010 if (!MapUtils.isEmpty(properties)) {
1011 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
1012 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr);
1013 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
1014 vertex.property(property.getKey().getProperty(), property.getValue());
1015 jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
1017 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
1019 } catch (Exception e) {
1020 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
1021 return JanusGraphClient.handleJanusGraphException(e);
1023 return JanusGraphOperationStatus.OK;
1026 public JanusGraphOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
1028 Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
1030 while (edges.hasNext()) {
1031 Edge edge = edges.next();
1032 Vertex secondVertex;
1033 Direction reverseDirection;
1034 if (direction == Direction.IN) {
1035 secondVertex = edge.outVertex();
1036 reverseDirection = Direction.OUT;
1038 secondVertex = edge.inVertex();
1039 reverseDirection = Direction.IN;
1042 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex());
1044 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
1045 if (!restOfEdges.hasNext()) {
1046 secondVertex.remove();
1047 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId());
1050 } catch (Exception e) {
1051 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e);
1052 return JanusGraphClient.handleJanusGraphException(e);
1054 return JanusGraphOperationStatus.OK;
1057 public Object getProperty(JanusGraphVertex vertex, String key) {
1058 PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key);
1059 return vertex.valueOrNull(propertyKey);
1062 public Object getProperty(Edge edge, EdgePropertyEnum key) {
1063 Object value = null;
1065 Property<Object> property = edge.property(key.getProperty());
1066 if (property != null) {
1067 value = property.orElse(null);
1068 if (value != null && key == EdgePropertyEnum.INSTANCES) {
1069 return JsonParserUtils.toList((String) value, String.class);
1073 } catch (Exception e) {
1087 public JanusGraphOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
1088 JanusGraphOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
1089 if (result != JanusGraphOperationStatus.OK) {
1090 logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
1093 JanusGraphOperationStatus createRelation;
1094 if (direction == Direction.IN) {
1095 createRelation = createEdge(vertexB, vertexA, label, null);
1097 createRelation = createEdge(vertexA, vertexB, label, null);
1099 if (createRelation != JanusGraphOperationStatus.OK) {
1100 return createRelation;
1102 return JanusGraphOperationStatus.OK;
1105 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
1106 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
1107 if (getVertexRes.isRight()) {
1108 return Either.right(getVertexRes.right().value());
1110 return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);