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 org.janusgraph.graphdb.query.JanusGraphPredicate;
25 import fj.data.Either;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.lang3.tuple.ImmutablePair;
28 import org.apache.tinkerpop.gremlin.structure.*;
29 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
30 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphClient;
31 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
32 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
34 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
35 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
36 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
37 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
38 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
39 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
40 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
41 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
42 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
43 import org.openecomp.sdc.common.log.wrappers.Logger;
44 import org.springframework.beans.factory.annotation.Qualifier;
46 import java.io.IOException;
48 import java.util.Map.Entry;
50 import static org.apache.commons.collections.CollectionUtils.isEmpty;
53 public class JanusGraphDao {
54 JanusGraphClient janusGraphClient;
56 private static Logger logger = Logger.getLogger(JanusGraphDao.class.getName());
58 public JanusGraphDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) {
59 this.janusGraphClient = janusGraphClient;
60 logger.info("** JanusGraphDao created");
63 public JanusGraphOperationStatus commit() {
64 logger.debug("#commit - The operation succeeded. Doing commit...");
65 return janusGraphClient.commit();
68 public JanusGraphOperationStatus rollback() {
69 logger.debug("#rollback - The operation failed. Doing rollback...");
70 return janusGraphClient.rollback();
73 public Either<JanusGraph, JanusGraphOperationStatus> getGraph() {
74 return janusGraphClient.getGraph();
82 public Either<GraphVertex, JanusGraphOperationStatus> createVertex(GraphVertex graphVertex) {
83 logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId());
84 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
87 JanusGraph tGraph = graph.left().value();
89 JanusGraphVertex vertex = tGraph.addVertex();
91 setVertexProperties(vertex, graphVertex);
93 graphVertex.setVertex(vertex);
95 return Either.left(graphVertex);
97 } catch (Exception e) {
98 logger.error(EcompLoggerErrorCode.DATA_ERROR, "JanusGraphDao",
99 "Failed to create Node for ID '{}'", (Object) graphVertex.getUniqueId(), e);
100 return Either.right(JanusGraphClient.handleJanusGraphException(e));
103 logger.debug("Failed to create vertex for ID '{}' {}", graphVertex.getUniqueId(), graph.right().value());
104 return Either.right(graph.right().value());
115 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) {
116 return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll);
119 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByLabel(VertexTypeEnum label) {
120 return janusGraphClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices()).left().bind(janusGraphVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, janusGraphVertices));
123 private Either<GraphVertex, JanusGraphOperationStatus> getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable<JanusGraphVertex> vertices) {
124 Iterator<JanusGraphVertex> iterator = vertices.iterator();
125 if (iterator.hasNext()) {
126 JanusGraphVertex vertex = iterator.next();
127 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
129 return Either.left(graphVertex);
131 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
142 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) {
144 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
145 if (graph.isLeft()) {
147 JanusGraph tGraph = graph.left().value();
149 @SuppressWarnings("unchecked")
150 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
152 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
153 if (iterator.hasNext()) {
154 JanusGraphVertex vertex = iterator.next();
155 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
157 return Either.left(graphVertex);
159 if (logger.isDebugEnabled()) {
160 logger.debug("No vertex in graph for key = {} and value = {} label = {}", name, value, label);
162 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
163 } catch (Exception e) {
164 if (logger.isDebugEnabled()) {
165 logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
167 return Either.right(JanusGraphClient.handleJanusGraphException(e));
171 if (logger.isDebugEnabled()) {
172 logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value());
174 return Either.right(graph.right().value());
183 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id) {
184 return getVertexById(id, JsonParseFlagEnum.ParseAll);
193 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
195 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
197 if (logger.isDebugEnabled()) {
198 logger.debug("No vertex in graph for id = {} ", id);
200 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
202 if (graph.isLeft()) {
204 JanusGraph tGraph = graph.left().value();
206 @SuppressWarnings("unchecked")
207 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
209 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
210 if (iterator.hasNext()) {
211 JanusGraphVertex vertex = iterator.next();
212 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
213 return Either.left(graphVertex);
215 if (logger.isDebugEnabled()) {
216 logger.debug("No vertex in graph for id = {}", id);
218 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
220 } catch (Exception e) {
221 if (logger.isDebugEnabled()) {
222 logger.debug("Failed to get vertex in graph for id {} ", id);
224 return Either.right(JanusGraphClient.handleJanusGraphException(e));
227 if (logger.isDebugEnabled()) {
228 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
230 return Either.right(graph.right().value());
234 private void setVertexProperties(JanusGraphVertex vertex, GraphVertex graphVertex) throws IOException {
236 if (graphVertex.getMetadataProperties() != null) {
237 for (Map.Entry<GraphPropertyEnum, Object> entry : graphVertex.getMetadataProperties().entrySet()) {
238 if (entry.getValue() != null) {
239 vertex.property(entry.getKey().getProperty(), entry.getValue());
243 vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
245 Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
247 String jsonStr = JsonParserUtils.toJson(json);
248 vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
251 Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
252 if (jsonMetadata != null) {
253 String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata);
254 vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
258 public void setVertexProperties(Vertex vertex, Map<String, Object> properties) throws IOException {
259 for (Map.Entry<String, Object> entry : properties.entrySet()) {
260 if (entry.getValue() != null) {
261 vertex.property(entry.getKey(), entry.getValue());
266 private GraphVertex createAndFill(JanusGraphVertex vertex, JsonParseFlagEnum parseFlag) {
267 GraphVertex graphVertex = new GraphVertex();
268 graphVertex.setVertex(vertex);
269 parseVertexProperties(graphVertex, parseFlag);
273 public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) {
274 JanusGraphVertex vertex = graphVertex.getVertex();
275 Map<GraphPropertyEnum, Object> properties = getVertexProperties(vertex);
276 VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
277 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
278 GraphPropertyEnum key = entry.getKey();
281 graphVertex.setUniqueId((String) entry.getValue());
284 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
287 String type = (String) entry.getValue();
289 graphVertex.setType(ComponentTypeEnum.valueOf(type));
293 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) {
294 String json = (String) entry.getValue();
295 Map<String, ? extends ToscaDataDefinition> jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson());
296 graphVertex.setJson(jsonObj);
300 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) {
301 String json = (String) entry.getValue();
302 Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
303 graphVertex.setMetadataJson(metadatObj);
307 graphVertex.addMetadataProperty(key, entry.getValue());
313 public JanusGraphOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
314 return createEdge(from.getVertex(), to.getVertex(), label, properties);
317 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
318 if (logger.isTraceEnabled()) {
319 logger.trace("Try to connect {} with {} label {} properties {}",
320 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
321 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties);
323 if (from == null || to == null) {
324 logger.trace("No JanusGraph vertex for id from {} or id to {}",
325 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
326 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
327 return JanusGraphOperationStatus.NOT_FOUND;
329 Edge edge = from.addEdge(label.name(), to);
330 JanusGraphOperationStatus status;
332 setEdgeProperties(edge, properties);
333 status = JanusGraphOperationStatus.OK;
334 } catch (IOException e) {
335 logger.error(EcompLoggerErrorCode.DATA_ERROR, "JanusGraphDao",
336 "Failed to set properties on edge properties [{}]", properties, e);
337 status = JanusGraphOperationStatus.GENERAL_ERROR;
342 public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
344 Map<GraphPropertyEnum, Object> result = new HashMap<>();
346 if (element != null && element.keys() != null && element.keys().size() > 0) {
347 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
349 for (Entry<String, Property> entry : propertyMap.entrySet()) {
350 String key = entry.getKey();
351 Object value = entry.getValue().value();
353 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
354 if (valueOf != null) {
355 result.put(valueOf, value);
358 // add print to properties that can't be converted by enum
363 public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
365 Map<EdgePropertyEnum, Object> result = new HashMap<>();
367 if (element != null && element.keys() != null && element.keys().size() > 0) {
368 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
370 for (Entry<String, Property> entry : propertyMap.entrySet()) {
371 String key = entry.getKey();
372 Object value = entry.getValue().value();
374 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
375 if (valueOf != null) {
376 if (valueOf == EdgePropertyEnum.INSTANCES) {
377 List<String> list = JsonParserUtils.toList((String) value, String.class);
378 result.put(valueOf, list);
380 result.put(valueOf, value);
388 public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) throws IOException {
390 if (properties != null && !properties.isEmpty()) {
392 Object[] propertyKeyValues = new Object[properties.size() * 2];
394 for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
395 propertyKeyValues[i++] = entry.getKey().getProperty();
396 Object value = entry.getValue();
397 if (entry.getKey() == EdgePropertyEnum.INSTANCES) {
398 String jsonStr = JsonParserUtils.toJson(value);
399 propertyKeyValues[i++] = jsonStr;
401 propertyKeyValues[i++] = entry.getValue();
404 ElementHelper.attachProperties(element, propertyKeyValues);
408 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
409 return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
412 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, JsonParseFlagEnum parseFlag) {
413 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
414 if (graph.isLeft()) {
416 JanusGraph tGraph = graph.left().value();
418 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
420 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
423 if (props != null && !props.isEmpty()) {
424 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
425 query = query.has(entry.getKey().getProperty(), entry.getValue());
428 Iterable<JanusGraphVertex> vertices = query.vertices();
429 if (vertices == null) {
430 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
433 Iterator<JanusGraphVertex> iterator = vertices.iterator();
434 List<GraphVertex> result = new ArrayList<>();
436 while (iterator.hasNext()) {
437 JanusGraphVertex vertex = iterator.next();
439 Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
440 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
442 result.add(graphVertex);
444 if (logger.isDebugEnabled()) {
445 logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
447 if (result.size() == 0) {
448 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
451 return Either.left(result);
452 } catch (Exception e) {
453 if (logger.isDebugEnabled()) {
454 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
456 return Either.right(JanusGraphClient.handleJanusGraphException(e));
460 if (logger.isDebugEnabled()) {
461 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
463 return Either.right(graph.right().value());
467 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, Map<GraphPropertyEnum, Object> hasNotProps, JsonParseFlagEnum parseFlag) {
468 return getByCriteria(type, props, hasNotProps, null, parseFlag);
471 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type,
472 final Map<GraphPropertyEnum, Object> hasProps, final Map<GraphPropertyEnum, Object> hasNotProps,
473 final Map<String, Entry<JanusGraphPredicate, Object>> predicates, final JsonParseFlagEnum parseFlag) {
474 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
475 if (graph.isLeft()) {
477 JanusGraph tGraph = graph.left().value();
479 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
481 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
484 if (hasProps != null && !hasProps.isEmpty()) {
485 for (Map.Entry<GraphPropertyEnum, Object> entry : hasProps.entrySet()) {
486 query = query.has(entry.getKey().getProperty(), entry.getValue());
489 if (hasNotProps != null && !hasNotProps.isEmpty()) {
490 for (Map.Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
491 if (entry.getValue() instanceof List) {
492 buildMultipleNegateQueryFromList(entry, query);
494 query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
498 if (predicates != null && !predicates.isEmpty()) {
499 for (Map.Entry<String, Entry<JanusGraphPredicate, Object>> entry : predicates.entrySet()) {
500 JanusGraphPredicate predicate = entry.getValue().getKey();
501 Object object = entry.getValue().getValue();
502 query = query.has(entry.getKey(), predicate, object);
505 Iterable<JanusGraphVertex> vertices = query.vertices();
506 if (vertices == null || !vertices.iterator().hasNext()) {
507 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
510 List<GraphVertex> result = new ArrayList<>();
511 vertices.forEach(vertex -> result.add(createAndFill(vertex, parseFlag)));
513 if (logger.isDebugEnabled()) {
514 logger.debug("Number of fetched nodes in graph for criteria : from type '{}' and properties '{}' is '{}'", type, hasProps, result.size());
517 return Either.left(result);
518 } catch (Exception e) {
519 if (logger.isDebugEnabled()) {
520 logger.debug("Failed to get by criteria for type '{}' and properties '{}'", type, hasProps, e);
522 return Either.right(JanusGraphClient.handleJanusGraphException(e));
526 if (logger.isDebugEnabled()) {
527 logger.debug("Failed to get by criteria for type '{}' and properties '{}'. Error : '{}'", type, hasProps, graph.right().value());
529 return Either.right(graph.right().value());
533 public Either<Iterator<Vertex>, JanusGraphOperationStatus> getCatalogOrArchiveVerticies(boolean isCatalog) {
534 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
535 if (graph.isLeft()) {
537 JanusGraph tGraph = graph.left().value();
539 String name = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName();
540 Iterable<JanusGraphVertex> vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), name).vertices();
541 if (vCatalogIter == null) {
542 logger.debug("Failed to fetch catalog vertex");
543 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
545 JanusGraphVertex catalogV = vCatalogIter.iterator().next();
546 if (catalogV == null) {
547 logger.debug("Failed to fetch catalog vertex");
548 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
550 String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name();
551 Iterator<Vertex> vertices = catalogV.vertices(Direction.OUT, edgeLabel);
553 return Either.left(vertices);
554 } catch (Exception e) {
555 if (logger.isDebugEnabled()) {
556 logger.debug("Failed get by criteria: ", e);
558 return Either.right(JanusGraphClient.handleJanusGraphException(e));
562 if (logger.isDebugEnabled()) {
563 logger.debug("Failed get by criteria : ", graph.right().value());
565 return Either.right(graph.right().value());
569 private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, JanusGraphQuery query) {
570 List<Object> negateList = (List<Object>) entry.getValue();
571 for (Object listItem : negateList) {
572 query.hasNot(entry.getKey().getProperty(), listItem);
578 * @param parentVertex
583 public Either<GraphVertex, JanusGraphOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
584 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertices(parentVertex, edgeLabel, parseFlag);
585 if (childrenVertecies.isRight()) {
586 return Either.right(childrenVertecies.right().value());
588 return Either.left(childrenVertecies.left().value().get(0));
593 * @param parentVertex
598 public Either<Vertex, JanusGraphOperationStatus> getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
599 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertices(parentVertex, edgeLabel, parseFlag);
600 if (childrenVertecies.isRight()) {
601 return Either.right(childrenVertecies.right().value());
603 return Either.left(childrenVertecies.left().value().get(0));
606 public Either<GraphVertex, JanusGraphOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
607 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertices(parentVertex, edgeLabel, parseFlag);
608 if (childrenVertecies.isRight()) {
609 return Either.right(childrenVertecies.right().value());
611 if (isEmpty(childrenVertecies.left().value())){
612 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
614 return Either.left(childrenVertecies.left().value().get(0));
617 public Either<Vertex, JanusGraphOperationStatus> getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
618 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertices(parentVertex, edgeLabel, parseFlag);
619 if (childrenVertecies.isRight() ) {
620 return Either.right(childrenVertecies.right().value());
622 if (isEmpty(childrenVertecies.left().value())){
623 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
625 return Either.left(childrenVertecies.left().value().get(0));
630 * @param parentVertex
635 public Either<List<GraphVertex>, JanusGraphOperationStatus> getChildrenVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
636 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.OUT);
639 public Either<List<GraphVertex>, JanusGraphOperationStatus> getParentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
640 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.IN);
643 public Either<List<Vertex>, JanusGraphOperationStatus> getParentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
644 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.IN);
647 private Either<List<Vertex>, JanusGraphOperationStatus> getAdjacentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
648 List<Vertex> list = new ArrayList<>();
650 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
651 if (graphRes.isRight()) {
652 logger.error("Failed to retrieve graph. status is {}", graphRes);
653 return Either.right(graphRes.right().value());
655 Iterator<Edge> edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name());
656 if (edgesCreatorIterator != null) {
657 while (edgesCreatorIterator.hasNext()) {
658 Edge edge = edgesCreatorIterator.next();
659 JanusGraphVertex vertex;
660 if (direction == Direction.IN) {
661 vertex = (JanusGraphVertex) edge.outVertex();
663 vertex = (JanusGraphVertex) edge.inVertex();
665 // GraphVertex graphVertex = createAndFill(vertex, parseFlag);
670 if (list.isEmpty()) {
671 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
673 } catch (Exception e) {
674 logger.error("Failed to perform graph operation ", e);
675 Either.right(JanusGraphClient.handleJanusGraphException(e));
678 return Either.left(list);
683 * @param parentVertex
688 public Either<List<Vertex>, JanusGraphOperationStatus> getChildrenVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
689 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.OUT);
692 private Either<List<GraphVertex>, JanusGraphOperationStatus> getAdjacentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
693 List<GraphVertex> list = new ArrayList<>();
695 Either<List<Vertex>, JanusGraphOperationStatus> adjacentVerticies = getAdjacentVertices(parentVertex.getVertex(), edgeLabel, parseFlag, direction);
696 if (adjacentVerticies.isRight()) {
697 return Either.right(adjacentVerticies.right().value());
699 adjacentVerticies.left().value().stream().forEach(vertex -> {
700 list.add(createAndFill((JanusGraphVertex) vertex, parseFlag));
703 return Either.left(list);
707 * Searches Edge by received label and criteria
712 * @return found edge or JanusGraphOperationStatus
714 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
716 Either<Edge, JanusGraphOperationStatus> result = null;
717 Edge matchingEdge = null;
718 String notFoundMsg = "No edges in graph for criteria";
720 JanusGraphVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
722 if (properties != null && !properties.isEmpty()) {
723 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
724 query = query.has(entry.getKey().getProperty(), entry.getValue());
728 Iterable<JanusGraphEdge> edges = query.edges();
730 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
731 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
733 Iterator<JanusGraphEdge> eIter = edges.iterator();
734 if (eIter.hasNext()) {
735 matchingEdge = eIter.next();
737 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
738 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
741 if (result == null) {
742 result = Either.left(matchingEdge);
744 } catch (Exception e) {
745 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
746 return Either.right(JanusGraphClient.handleJanusGraphException(e));
751 public Either<Edge, JanusGraphOperationStatus> getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
752 Either<Edge, JanusGraphOperationStatus> result = null;
753 Edge matchingEdge = null;
754 String notFoundMsg = "No edges in graph for criteria";
757 Iterator<Edge> edges = vertex.getVertex().edges(Direction.OUT, label.name());
758 while (edges.hasNext()) {
759 matchingEdge = edges.next();
760 Vertex childV = matchingEdge.inVertex();
761 Map<GraphPropertyEnum, Object> vertexProperties = getVertexProperties(childV);
762 Optional<Entry<GraphPropertyEnum, Object>> findNotMatch = properties.entrySet().stream().filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst();
763 if (!findNotMatch.isPresent()) {
764 result = Either.left(matchingEdge);
767 if (result == null) {
769 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
770 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
772 } catch (Exception e) {
773 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
774 return Either.right(JanusGraphClient.handleJanusGraphException(e));
780 * Deletes Edge by received label and criteria
787 public Either<Edge, JanusGraphOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
788 Either<Edge, JanusGraphOperationStatus> result = null;
790 result = getBelongingEdgeByCriteria(vertex, label, properties);
791 if (result.isLeft()) {
792 Edge edge = result.left().value();
793 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
795 result = Either.left(edge);
797 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
799 } catch (Exception e) {
800 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex == null ? "NULL" : vertex.getUniqueId(), e);
801 return Either.right(JanusGraphClient.handleJanusGraphException(e));
806 @SuppressWarnings("unchecked")
808 * Deletes an edge between vertices fromVertex and toVertex according to received label
816 public Either<Edge, JanusGraphOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
817 return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false);
820 public Either<Edge, JanusGraphOperationStatus> deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
821 return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true);
824 public Either<Edge, JanusGraphOperationStatus> deleteEdge(JanusGraphVertex fromVertex, JanusGraphVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) {
825 Either<Edge, JanusGraphOperationStatus> result = null;
826 Vertex problemV = null;
828 Iterable<JanusGraphEdge> edges = fromVertex.query().labels(label.name()).edges();
829 Iterator<JanusGraphEdge> eIter = edges.iterator();
830 while (eIter.hasNext()) {
831 Edge edge = eIter.next();
832 problemV = edge.inVertex();
833 String currVertexUniqueId = null;
835 currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
836 }catch (Exception e){
837 // AutoHealing procedure
838 logger.info( "Corrupted vertex and edge were found and deleted {}",e);
839 if ( problemV != null ) {
840 Map<GraphPropertyEnum, Object> props = getVertexProperties(problemV);
841 logger.debug( "problematic Vertex properties:");
842 logger.debug( "props size: {}", props.size());
843 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
844 logger.debug( "{}{}",entry.getKey() + ":" + entry.getValue());
846 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertices = getChildrenVertices(problemV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
847 if(childrenVertices.isLeft()){
848 childrenVertices.left().value().size();
849 logger.debug( "number of children that problematic Vertex has: {}", props.size());
853 }catch (Exception e1){
854 logger.debug( "failed to remove problematic edge. {}", e1);
858 }catch (Exception e2){
859 logger.debug( "failed to remove problematic vertex . {}", e2);
865 if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) {
866 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
868 result = Either.left(edge);
874 if (result == null) {
875 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
876 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
878 } catch (Exception e) {
880 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e);
881 return Either.right(JanusGraphClient.handleJanusGraphException(e));
886 public JanusGraphOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
888 Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
890 while (edges.hasNext()) {
891 Edge edge = edges.next();
894 } catch (Exception e) {
895 logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
896 return JanusGraphClient.handleJanusGraphException(e);
898 return JanusGraphOperationStatus.OK;
902 * Updates vertex properties. Note that graphVertex argument should contain updated data
907 public Either<GraphVertex, JanusGraphOperationStatus> updateVertex(GraphVertex graphVertex) {
908 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
910 graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
911 setVertexProperties(graphVertex.getVertex(), graphVertex);
913 } catch (Exception e) {
914 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
915 return Either.right(JanusGraphClient.handleJanusGraphException(e));
917 return Either.left(graphVertex);
921 * Fetches vertices by uniqueId according to received parse flag
923 * @param verticesToGet
926 public Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesByUniqueIdAndParseFlag(Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
928 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> result = null;
929 Map<String, GraphVertex> vertices = new HashMap<>();
930 JanusGraphOperationStatus titatStatus;
931 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = null;
932 for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
933 if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
934 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
935 } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
936 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue());
938 if (getVertexRes == null) {
939 titatStatus = JanusGraphOperationStatus.ILLEGAL_ARGUMENT;
940 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus);
941 return Either.right(titatStatus);
943 if (getVertexRes.isRight()) {
944 titatStatus = getVertexRes.right().value();
945 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
946 result = Either.right(titatStatus);
949 vertices.put(entry.getKey(), getVertexRes.left().value());
952 if (result == null) {
953 result = Either.left(vertices);
959 * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
967 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
968 return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
971 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
972 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",
973 toVertex!=null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL");
975 JanusGraphOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
976 if (result == JanusGraphOperationStatus.OK) {
983 * Replaces previous label of edge with new label
991 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel,
992 EdgeLabelEnum newLabel) {
994 Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
995 if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
996 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
997 "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel,
998 fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
999 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
1000 return JanusGraphOperationStatus.NOT_FOUND;
1002 return replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
1007 * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
1014 public JanusGraphOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
1016 if (!MapUtils.isEmpty(properties)) {
1017 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
1018 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr);
1019 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
1020 vertex.property(property.getKey().getProperty(), property.getValue());
1021 jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
1023 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
1025 } catch (Exception e) {
1026 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
1027 return JanusGraphClient.handleJanusGraphException(e);
1029 return JanusGraphOperationStatus.OK;
1032 public JanusGraphOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
1034 Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
1036 while (edges.hasNext()) {
1037 Edge edge = edges.next();
1038 Vertex secondVertex;
1039 Direction reverseDirection;
1040 if (direction == Direction.IN) {
1041 secondVertex = edge.outVertex();
1042 reverseDirection = Direction.OUT;
1044 secondVertex = edge.inVertex();
1045 reverseDirection = Direction.IN;
1048 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex());
1050 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
1051 if (!restOfEdges.hasNext()) {
1052 secondVertex.remove();
1053 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId());
1056 } catch (Exception e) {
1057 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e);
1058 return JanusGraphClient.handleJanusGraphException(e);
1060 return JanusGraphOperationStatus.OK;
1063 public Object getProperty(JanusGraphVertex vertex, String key) {
1064 PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key);
1065 return vertex.valueOrNull(propertyKey);
1068 public Object getProperty(Edge edge, EdgePropertyEnum key) {
1069 Object value = null;
1071 Property<Object> property = edge.property(key.getProperty());
1072 if (property != null) {
1073 value = property.orElse(null);
1074 if (value != null && key == EdgePropertyEnum.INSTANCES) {
1075 return JsonParserUtils.toList((String) value, String.class);
1079 } catch (Exception e) {
1093 public JanusGraphOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
1094 JanusGraphOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
1095 if (result != JanusGraphOperationStatus.OK) {
1096 logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
1099 JanusGraphOperationStatus createRelation;
1100 if (direction == Direction.IN) {
1101 createRelation = createEdge(vertexB, vertexA, label, null);
1103 createRelation = createEdge(vertexA, vertexB, label, null);
1105 if (createRelation != JanusGraphOperationStatus.OK) {
1106 return createRelation;
1108 return JanusGraphOperationStatus.OK;
1111 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
1112 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
1113 if (getVertexRes.isRight()) {
1114 return Either.right(getVertexRes.right().value());
1116 return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);