Add lombok support to simple classes
[sdc.git] / catalog-dao / src / main / java / org / openecomp / sdc / be / dao / jsongraph / JanusGraphDao.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
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
10  * 
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  * 
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=========================================================
19  */
20
21 package org.openecomp.sdc.be.dao.jsongraph;
22
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;
43
44 import java.io.IOException;
45 import java.util.*;
46 import java.util.Map.Entry;
47
48 import static org.apache.commons.collections.CollectionUtils.isEmpty;
49
50
51 public class JanusGraphDao {
52     JanusGraphClient janusGraphClient;
53
54     private static Logger logger = Logger.getLogger(JanusGraphDao.class.getName());
55
56     public JanusGraphDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) {
57         this.janusGraphClient = janusGraphClient;
58         logger.info("** JanusGraphDao created");
59     }
60
61     public JanusGraphOperationStatus commit() {
62         logger.debug("#commit - The operation succeeded. Doing commit...");
63         return janusGraphClient.commit();
64     }
65
66     public JanusGraphOperationStatus rollback() {
67         logger.debug("#rollback - The operation failed. Doing rollback...");
68         return janusGraphClient.rollback();
69     }
70
71     public Either<JanusGraph, JanusGraphOperationStatus> getGraph() {
72         return janusGraphClient.getGraph();
73     }
74
75     /**
76      * 
77      * @param graphVertex
78      * @return
79      */
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();
83         if (graph.isLeft()) {
84             try {
85                 JanusGraph tGraph = graph.left().value();
86
87                 JanusGraphVertex vertex = tGraph.addVertex();
88
89                 setVertexProperties(vertex, graphVertex);
90
91                 graphVertex.setVertex(vertex);
92
93                 return Either.left(graphVertex);
94
95             } catch (Exception e) {
96                 logger.debug("Failed to create Node for ID [{}]", graphVertex.getUniqueId(), e);
97                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
98             }
99         } else {
100             logger.debug("Failed to create vertex for ID [{}]  {}", graphVertex.getUniqueId(), graph.right().value());
101             return Either.right(graph.right().value());
102         }
103     }
104
105     /**
106      * 
107      * @param name
108      * @param value
109      * @param label
110      * @return
111      */
112     public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) {
113         return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll);
114     }
115
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));
118     }
119
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);
125
126             return Either.left(graphVertex);
127         }
128         return Either.right(JanusGraphOperationStatus.NOT_FOUND);
129     }
130
131     /**
132      * 
133      * @param name
134      * @param value
135      * @param label
136      * @param parseFlag
137      * @return
138      */
139     public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label, JsonParseFlagEnum parseFlag) {
140
141         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
142         if (graph.isLeft()) {
143             try {
144                 JanusGraph tGraph = graph.left().value();
145
146                 @SuppressWarnings("unchecked")
147                 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(name.getProperty(), value).has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
148
149                 java.util.Iterator<JanusGraphVertex> iterator = vertecies.iterator();
150                 if (iterator.hasNext()) {
151                     JanusGraphVertex vertex = iterator.next();
152                     GraphVertex graphVertex = createAndFill(vertex, parseFlag);
153
154                     return Either.left(graphVertex);
155                 }
156                 if (logger.isDebugEnabled()) {
157                     logger.debug("No vertex in graph for key = {}  and value = {}   label = {}" + name, value, label);
158                 }
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);
163                 }
164                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
165             }
166
167         } else {
168             if (logger.isDebugEnabled()) {
169                 logger.debug("No vertex in graph for key ={} and value = {}  label = {} error :{}", name, value, label, graph.right().value());
170             }
171             return Either.right(graph.right().value());
172         }
173     }
174
175     /**
176      * 
177      * @param id
178      * @return
179      */
180     public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id) {
181         return getVertexById(id, JsonParseFlagEnum.ParseAll);
182     }
183
184     /**
185      * 
186      * @param id
187      * @param parseFlag
188      * @return
189      */
190     public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
191
192         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
193         if (id == null) {
194             if (logger.isDebugEnabled()) {
195                 logger.debug("No vertex in graph for id = {} ", id);
196             }
197             return Either.right(JanusGraphOperationStatus.NOT_FOUND);
198         }
199         if (graph.isLeft()) {
200             try {
201                 JanusGraph tGraph = graph.left().value();
202
203                 @SuppressWarnings("unchecked")
204                 Iterable<JanusGraphVertex> vertecies = tGraph.query().has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
205
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);
211                 } else {
212                     if (logger.isDebugEnabled()) {
213                         logger.debug("No vertex in graph for id = {}", id);
214                     }
215                     return Either.right(JanusGraphOperationStatus.NOT_FOUND);
216                 }
217             } catch (Exception e) {
218                 if (logger.isDebugEnabled()) {
219                     logger.debug("Failed to get vertex in graph for id {} ", id);
220                 }
221                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
222             }
223         } else {
224             if (logger.isDebugEnabled()) {
225                 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
226             }
227             return Either.right(graph.right().value());
228         }
229     }
230
231     private void setVertexProperties(JanusGraphVertex vertex, GraphVertex graphVertex) throws IOException {
232
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());
237                 }
238             }
239         }
240         vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
241
242         Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
243         if (json != null) {
244             String jsonStr = JsonParserUtils.toJson(json);
245             vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
246
247         }
248         Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
249         if (jsonMetadata != null) {
250             String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata);
251             vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
252         }
253     }
254
255     public void setVertexProperties(Vertex vertex, Map<String, Object> properties) {
256         for (Map.Entry<String, Object> entry : properties.entrySet()) {
257             if (entry.getValue() != null) {
258                 vertex.property(entry.getKey(), entry.getValue());
259             }
260         }
261     }
262
263     private GraphVertex createAndFill(JanusGraphVertex vertex, JsonParseFlagEnum parseFlag) {
264         GraphVertex graphVertex = new GraphVertex();
265         graphVertex.setVertex(vertex);
266         parseVertexProperties(graphVertex, parseFlag);
267         return graphVertex;
268     }
269
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();
276             switch (key) {
277             case UNIQUE_ID:
278                 graphVertex.setUniqueId((String) entry.getValue());
279                 break;
280             case LABEL:
281                 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
282                 break;
283             case COMPONENT_TYPE:
284                 String type = (String) entry.getValue();
285                 if (type != null) {
286                     graphVertex.setType(ComponentTypeEnum.valueOf(type));
287                 }
288                 break;
289             case JSON:
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);
294                 }
295                 break;
296             case METADATA:
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);
301                 }
302                 break;
303             default:
304                 graphVertex.addMetadataProperty(key, entry.getValue());
305                 break;
306             }
307         }
308     }
309
310     public JanusGraphOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
311         return createEdge(from.getVertex(), to.getVertex(), label, properties);
312     }
313
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);
319         }
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;
325         }
326         Edge edge = from.addEdge(label.name(), to);
327         JanusGraphOperationStatus status;
328         try {
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;
334         }
335         return status;
336     }
337
338     public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
339
340         Map<GraphPropertyEnum, Object> result = new HashMap<>();
341
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()]));
344
345             for (Entry<String, Property> entry : propertyMap.entrySet()) {
346                 String key = entry.getKey();
347                 Object value = entry.getValue().value();
348
349                 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
350                 if (valueOf != null) {
351                     result.put(valueOf, value);
352                 }
353             }
354         }
355         return result;
356     }
357
358     public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
359
360         Map<EdgePropertyEnum, Object> result = new HashMap<>();
361
362         if (element != null && element.keys() != null && element.keys().size() > 0) {
363             Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
364
365             for (Entry<String, Property> entry : propertyMap.entrySet()) {
366                 String key = entry.getKey();
367                 Object value = entry.getValue().value();
368
369                 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
370                 if (valueOf != null) {
371                     if (valueOf == EdgePropertyEnum.INSTANCES) {
372                         List<String> list = JsonParserUtils.toList((String) value, String.class);
373                         result.put(valueOf, list);
374                     } else {
375                         result.put(valueOf, value);
376                     }
377                 }
378             }
379         }
380         return result;
381     }
382
383     public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) throws IOException {
384
385         if (properties != null && !properties.isEmpty()) {
386
387             Object[] propertyKeyValues = new Object[properties.size() * 2];
388             int i = 0;
389             for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
390                 propertyKeyValues[i++] = entry.getKey().getProperty();
391                 Object value = entry.getValue();
392                 if (entry.getKey() == EdgePropertyEnum.INSTANCES) {
393                     String jsonStr = JsonParserUtils.toJson(value);
394                     propertyKeyValues[i++] = jsonStr;
395                 } else {
396                     propertyKeyValues[i++] = entry.getValue();
397                 }
398             }
399             ElementHelper.attachProperties(element, propertyKeyValues);
400         }
401     }
402
403     public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
404         return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
405     }
406
407     public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, JsonParseFlagEnum parseFlag) {
408         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
409         if (graph.isLeft()) {
410             try {
411                 JanusGraph tGraph = graph.left().value();
412
413                 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
414                 if (type != null) {
415                     query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
416                 }
417
418                 if (props != null && !props.isEmpty()) {
419                     for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
420                         query = query.has(entry.getKey().getProperty(), entry.getValue());
421                     }
422                 }
423                 Iterable<JanusGraphVertex> vertices = query.vertices();
424                 if (vertices == null) {
425                     return Either.right(JanusGraphOperationStatus.NOT_FOUND);
426                 }
427
428                 Iterator<JanusGraphVertex> iterator = vertices.iterator();
429                 List<GraphVertex> result = new ArrayList<>();
430
431                 while (iterator.hasNext()) {
432                     JanusGraphVertex vertex = iterator.next();
433
434                     Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
435                     GraphVertex graphVertex = createAndFill(vertex, parseFlag);
436
437                     result.add(graphVertex);
438                 }
439                 if (logger.isDebugEnabled()) {
440                     logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
441                 }
442                 if (result.size() == 0) {
443                     return Either.right(JanusGraphOperationStatus.NOT_FOUND);
444                 }
445
446                 return Either.left(result);
447             } catch (Exception e) {
448                 if (logger.isDebugEnabled()) {
449                     logger.debug("Failed  get by  criteria for type = {} and properties = {}", type, props, e);
450                 }
451                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
452             }
453
454         } else {
455             if (logger.isDebugEnabled()) {
456                 logger.debug("Failed  get by  criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
457             }
458             return Either.right(graph.right().value());
459         }
460     }
461
462     public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props, Map<GraphPropertyEnum, Object> hasNotProps, JsonParseFlagEnum parseFlag) {
463         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
464         if (graph.isLeft()) {
465             try {
466                 JanusGraph tGraph = graph.left().value();
467
468                 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
469                 if (type != null) {
470                     query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
471                 }
472
473                 if (props != null && !props.isEmpty()) {
474                     for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
475                         query = query.has(entry.getKey().getProperty(), entry.getValue());
476                     }
477                 }
478                 if (hasNotProps != null && !hasNotProps.isEmpty()) {
479                     for (Map.Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
480                         if (entry.getValue() instanceof List) {
481                             buildMultipleNegateQueryFromList(entry, query);
482                         } else {
483                             query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
484                         }
485                     }
486                 }
487                 Iterable<JanusGraphVertex> vertices = query.vertices();
488                 if (vertices == null) {
489                     return Either.right(JanusGraphOperationStatus.NOT_FOUND);
490                 }
491
492                 Iterator<JanusGraphVertex> iterator = vertices.iterator();
493                 List<GraphVertex> result = new ArrayList<>();
494
495                 while (iterator.hasNext()) {
496                     JanusGraphVertex vertex = iterator.next();
497
498                     Map<GraphPropertyEnum, Object> newProp = getVertexProperties(vertex);
499                     GraphVertex graphVertex = createAndFill(vertex, parseFlag);
500
501                     result.add(graphVertex);
502                 }
503                 if (logger.isDebugEnabled()) {
504                     logger.debug("Number of fetced nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
505                 }
506                 if (result.size() == 0) {
507                     return Either.right(JanusGraphOperationStatus.NOT_FOUND);
508                 }
509
510                 return Either.left(result);
511             } catch (Exception e) {
512                 if (logger.isDebugEnabled()) {
513                     logger.debug("Failed  get by  criteria for type = {} and properties = {}", type, props, e);
514                 }
515                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
516             }
517
518         } else {
519             if (logger.isDebugEnabled()) {
520                 logger.debug("Failed  get by  criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
521             }
522             return Either.right(graph.right().value());
523         }
524     }
525
526     public Either<Iterator<Vertex>, JanusGraphOperationStatus> getCatalogOrArchiveVerticies(boolean isCatalog) {
527         Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
528         if (graph.isLeft()) {
529             try {
530                 JanusGraph tGraph = graph.left().value();
531
532                 String name = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName();
533                 Iterable<JanusGraphVertex> vCatalogIter = tGraph.query().has(GraphPropertyEnum.LABEL.getProperty(), name).vertices();
534                 if (vCatalogIter == null) {
535                     logger.debug("Failed to fetch catalog vertex");
536                     return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
537                 }
538                 JanusGraphVertex catalogV = vCatalogIter.iterator().next();
539                 if (catalogV == null) {
540                     logger.debug("Failed to fetch catalog vertex");
541                     return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
542                 }
543                 String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name();
544                 Iterator<Vertex> vertices = catalogV.vertices(Direction.OUT, edgeLabel);
545
546                 return Either.left(vertices);
547             } catch (Exception e) {
548                 if (logger.isDebugEnabled()) {
549                     logger.debug("Failed  get by  criteria: ", e);
550                 }
551                 return Either.right(JanusGraphClient.handleJanusGraphException(e));
552             }
553
554         } else {
555             if (logger.isDebugEnabled()) {
556                 logger.debug("Failed  get by  criteria : ", graph.right().value());
557             }
558             return Either.right(graph.right().value());
559         }
560     }
561
562     private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, JanusGraphQuery query) {
563         List<Object> negateList = (List<Object>) entry.getValue();
564         for (Object listItem : negateList) {
565             query.hasNot(entry.getKey().getProperty(), listItem);
566         }
567     }
568
569     /**
570      * 
571      * @param parentVertex
572      * @param edgeLabel
573      * @param parseFlag
574      * @return
575      */
576     public Either<GraphVertex, JanusGraphOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
577         Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag);
578         if (childrenVertecies.isRight()) {
579             return Either.right(childrenVertecies.right().value());
580         }
581         return Either.left(childrenVertecies.left().value().get(0));
582     }
583
584     /**
585      *
586      * @param parentVertex
587      * @param edgeLabel
588      * @param parseFlag
589      * @return
590      */
591     public Either<Vertex, JanusGraphOperationStatus> getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
592         Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getChildrenVertecies(parentVertex, edgeLabel, parseFlag);
593         if (childrenVertecies.isRight()) {
594             return Either.right(childrenVertecies.right().value());
595         }
596         return Either.left(childrenVertecies.left().value().get(0));
597     }
598
599     public Either<GraphVertex, JanusGraphOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
600         Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag);
601         if (childrenVertecies.isRight()) {
602             return Either.right(childrenVertecies.right().value());
603         }
604         if (isEmpty(childrenVertecies.left().value())){
605             return Either.right(JanusGraphOperationStatus.NOT_FOUND);
606         }
607         return Either.left(childrenVertecies.left().value().get(0));
608     }
609
610     public Either<Vertex, JanusGraphOperationStatus> getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
611         Either<List<Vertex>, JanusGraphOperationStatus> childrenVertecies = getParentVertecies(parentVertex, edgeLabel, parseFlag);
612         if (childrenVertecies.isRight() ) {
613             return Either.right(childrenVertecies.right().value());
614         }
615         if (isEmpty(childrenVertecies.left().value())){
616             return Either.right(JanusGraphOperationStatus.NOT_FOUND);
617         }
618         return Either.left(childrenVertecies.left().value().get(0));
619     }
620
621     /**
622      * 
623      * @param parentVertex
624      * @param edgeLabel
625      * @param parseFlag
626      * @return
627      */
628     public Either<List<GraphVertex>, JanusGraphOperationStatus> getChildrenVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
629         return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT);
630     }
631
632     public Either<List<GraphVertex>, JanusGraphOperationStatus> getParentVertecies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
633         return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN);
634     }
635
636     public Either<List<Vertex>, JanusGraphOperationStatus> getParentVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
637         return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.IN);
638     }
639
640     private Either<List<Vertex>, JanusGraphOperationStatus> getAdjacentVerticies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
641         List<Vertex> list = new ArrayList<>();
642         try {
643             Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
644             if (graphRes.isRight()) {
645                 logger.error("Failed to retrieve graph. status is {}", graphRes);
646                 return Either.right(graphRes.right().value());
647             }
648             Iterator<Edge> edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name());
649             if (edgesCreatorIterator != null) {
650                 while (edgesCreatorIterator.hasNext()) {
651                     Edge edge = edgesCreatorIterator.next();
652                     JanusGraphVertex vertex;
653                     if (direction == Direction.IN) {
654                         vertex = (JanusGraphVertex) edge.outVertex();
655                     } else {
656                         vertex = (JanusGraphVertex) edge.inVertex();
657                     }
658                     // GraphVertex graphVertex = createAndFill(vertex, parseFlag);
659
660                     list.add(vertex);
661                 }
662             }
663             if (list.isEmpty()) {
664                 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
665             }
666         } catch (Exception e) {
667             logger.error("Failed to perform graph operation ", e);
668             Either.right(JanusGraphClient.handleJanusGraphException(e));
669         }
670
671         return Either.left(list);
672     }
673
674     /**
675      *
676      * @param parentVertex
677      * @param edgeLabel
678      * @param parseFlag
679      * @return
680      */
681     public Either<List<Vertex>, JanusGraphOperationStatus> getChildrenVertecies(Vertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag) {
682         return getAdjacentVerticies(parentVertex, edgeLabel, parseFlag, Direction.OUT);
683     }
684
685     private Either<List<GraphVertex>, JanusGraphOperationStatus> getAdjacentVerticies(GraphVertex parentVertex, EdgeLabelEnum edgeLabel, JsonParseFlagEnum parseFlag, Direction direction) {
686         List<GraphVertex> list = new ArrayList<>();
687
688         Either<List<Vertex>, JanusGraphOperationStatus> adjacentVerticies = getAdjacentVerticies(parentVertex.getVertex(), edgeLabel, parseFlag, direction);
689         if (adjacentVerticies.isRight()) {
690             return Either.right(adjacentVerticies.right().value());
691         }
692         adjacentVerticies.left().value().stream().forEach(vertex -> {
693             list.add(createAndFill((JanusGraphVertex) vertex, parseFlag));
694         });
695
696         return Either.left(list);
697     }
698
699     /**
700      * Searches Edge by received label and criteria
701      * 
702      * @param vertex
703      * @param label
704      * @param properties
705      * @return found edge or JanusGraphOperationStatus
706      */
707     public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
708
709         Either<Edge, JanusGraphOperationStatus> result = null;
710         Edge matchingEdge = null;
711         String notFoundMsg = "No edges in graph for criteria";
712         try {
713             JanusGraphVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
714
715             if (properties != null && !properties.isEmpty()) {
716                 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
717                     query = query.has(entry.getKey().getProperty(), entry.getValue());
718                 }
719             }
720
721             Iterable<JanusGraphEdge> edges = query.edges();
722             if (edges == null) {
723                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
724                 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
725             } else {
726                 Iterator<JanusGraphEdge> eIter = edges.iterator();
727                 if (eIter.hasNext()) {
728                     matchingEdge = eIter.next();
729                 } else {
730                     CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
731                     result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
732                 }
733             }
734             if (result == null) {
735                 result = Either.left(matchingEdge);
736             }
737         } catch (Exception e) {
738             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
739             return Either.right(JanusGraphClient.handleJanusGraphException(e));
740         }
741         return result;
742     }
743
744     public Either<Edge, JanusGraphOperationStatus> getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
745         Either<Edge, JanusGraphOperationStatus> result = null;
746         Edge matchingEdge = null;
747         String notFoundMsg = "No edges in graph for criteria";
748         try {
749
750             Iterator<Edge> edges = vertex.getVertex().edges(Direction.OUT, label.name());
751             while (edges.hasNext()) {
752                 matchingEdge = edges.next();
753                 Vertex childV = matchingEdge.inVertex();
754                 Map<GraphPropertyEnum, Object> vertexProperties = getVertexProperties(childV);
755                 Optional<Entry<GraphPropertyEnum, Object>> findNotMatch = properties.entrySet().stream().filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst();
756                 if (!findNotMatch.isPresent()) {
757                     result = Either.left(matchingEdge);
758                 }
759             }
760             if (result == null) {
761                 //no match 
762                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
763                 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
764             }
765         } catch (Exception e) {
766             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}", vertex.getUniqueId(), e);
767             return Either.right(JanusGraphClient.handleJanusGraphException(e));
768         }
769         return result;
770     }
771
772     /**
773      * Deletes Edge by received label and criteria
774      * 
775      * @param vertex
776      * @param label
777      * @param properties
778      * @return
779      */
780     public Either<Edge, JanusGraphOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
781         Either<Edge, JanusGraphOperationStatus> result = null;
782         try {
783             result = getBelongingEdgeByCriteria(vertex, label, properties);
784             if (result.isLeft()) {
785                 Edge edge = result.left().value();
786                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
787                 edge.remove();
788                 result = Either.left(edge);
789             } else {
790                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(), vertex.getUniqueId());
791             }
792         } catch (Exception e) {
793             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}", vertex == null ? "NULL" : vertex.getUniqueId(), e);
794             return Either.right(JanusGraphClient.handleJanusGraphException(e));
795         }
796         return result;
797     }
798
799     @SuppressWarnings("unchecked")
800     /**
801      * Deletes an edge between vertices fromVertex and toVertex according to received label
802      * 
803      * @param fromVertex
804      * @param toVertex
805      * @param label
806      * @return
807      */
808
809     public Either<Edge, JanusGraphOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
810         return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false);
811     }
812
813     public Either<Edge, JanusGraphOperationStatus> deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
814         return deleteEdge(fromVertex.getVertex(), toVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true);
815     }
816
817     public Either<Edge, JanusGraphOperationStatus> deleteEdge(JanusGraphVertex fromVertex, JanusGraphVertex toVertex, EdgeLabelEnum label, String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) {
818         Either<Edge, JanusGraphOperationStatus> result = null;
819         try {
820             Iterable<JanusGraphEdge> edges = fromVertex.query().labels(label.name()).edges();
821             Iterator<JanusGraphEdge> eIter = edges.iterator();
822             while (eIter.hasNext()) {
823                 Edge edge = eIter.next();
824                 String currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
825                 if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) {
826                     CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
827                     edge.remove();
828                     result = Either.left(edge);
829                     if (!deleteAll) {
830                         break;
831                     }
832                 }
833             }
834             if (result == null) {
835                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ", label.name(), uniqueIdFrom, uniqueIdTo);
836                 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
837             }
838         } catch (Exception e) {
839             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo, e);
840             return Either.right(JanusGraphClient.handleJanusGraphException(e));
841         }
842         return result;
843     }
844
845     public JanusGraphOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
846         try {
847             Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
848
849             while (edges.hasNext()) {
850                 Edge edge = edges.next();
851                 edge.remove();
852             }
853         } catch (Exception e) {
854             logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
855             return JanusGraphClient.handleJanusGraphException(e);
856         }
857         return JanusGraphOperationStatus.OK;
858     }
859
860     /**
861      * Updates vertex properties. Note that graphVertex argument should contain updated data
862      * 
863      * @param graphVertex
864      * @return
865      */
866     public Either<GraphVertex, JanusGraphOperationStatus> updateVertex(GraphVertex graphVertex) {
867         CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
868         try {
869             graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
870             setVertexProperties(graphVertex.getVertex(), graphVertex);
871
872         } catch (Exception e) {
873             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
874             return Either.right(JanusGraphClient.handleJanusGraphException(e));
875         }
876         return Either.left(graphVertex);
877     }
878
879     /**
880      * Fetches vertices by uniqueId according to received parse flag
881      * 
882      * @param verticesToGet
883      * @return
884      */
885     public Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesByUniqueIdAndParseFlag(Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
886
887         Either<Map<String, GraphVertex>, JanusGraphOperationStatus> result = null;
888         Map<String, GraphVertex> vertices = new HashMap<>();
889         JanusGraphOperationStatus titatStatus;
890         Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = null;
891         for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
892             if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
893                 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
894             } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
895                 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER, entry.getValue().getValue());
896             }
897             if (getVertexRes == null) {
898                 titatStatus = JanusGraphOperationStatus.ILLEGAL_ARGUMENT;
899                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(), titatStatus);
900                 return Either.right(titatStatus);
901             }
902             if (getVertexRes.isRight()) {
903                 titatStatus = getVertexRes.right().value();
904                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
905                 result = Either.right(titatStatus);
906                 break;
907             } else {
908                 vertices.put(entry.getKey(), getVertexRes.left().value());
909             }
910         }
911         if (result == null) {
912             result = Either.left(vertices);
913         }
914         return result;
915     }
916
917     /**
918      * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
919      * 
920      * @param from
921      * @param to
922      * @param label
923      * @param edgeToCopy
924      * @return
925      */
926     public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
927         return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
928     }
929
930     public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
931         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",
932                 toVertex!=null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL");
933
934         JanusGraphOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
935         if (result == JanusGraphOperationStatus.OK) {
936             prevEdge.remove();
937         }
938         return result;
939     }
940
941     /**
942      * Replaces previous label of edge with new label
943      * 
944      * @param fromVertex
945      * @param toVertex
946      * @param prevLabel
947      * @param newLabel
948      * @return
949      */
950     public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
951
952         JanusGraphOperationStatus result = null;
953         Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
954         if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
955             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
956                     toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
957             result = JanusGraphOperationStatus.NOT_FOUND;
958         }
959         if (result == null) {
960             result = replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
961         }
962         return result;
963     }
964
965     /**
966      * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
967      * 
968      * 
969      * @param vertex
970      * @param properties
971      * @return
972      */
973     public JanusGraphOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
974         try {
975             if (!MapUtils.isEmpty(properties)) {
976                 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
977                 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr);
978                 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
979                     vertex.property(property.getKey().getProperty(), property.getValue());
980                     jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
981                 }
982                 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
983             }
984         } catch (Exception e) {
985             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}", vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
986             return JanusGraphClient.handleJanusGraphException(e);
987         }
988         return JanusGraphOperationStatus.OK;
989     }
990
991     public JanusGraphOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
992         try {
993             Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
994
995             while (edges.hasNext()) {
996                 Edge edge = edges.next();
997                 Vertex secondVertex;
998                 Direction reverseDirection;
999                 if (direction == Direction.IN) {
1000                     secondVertex = edge.outVertex();
1001                     reverseDirection = Direction.OUT;
1002                 } else {
1003                     secondVertex = edge.inVertex();
1004                     reverseDirection = Direction.IN;
1005                 }
1006                 edge.remove();
1007                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge  {} with direction {} was removed from {}", label.name(), direction, vertex.getVertex());
1008
1009                 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
1010                 if (!restOfEdges.hasNext()) {
1011                     secondVertex.remove();
1012                     CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex  {} was removed ", vertex.getUniqueId());
1013                 }
1014             }
1015         } catch (Exception e) {
1016             CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction, vertex.getUniqueId(), e);
1017             return JanusGraphClient.handleJanusGraphException(e);
1018         }
1019         return JanusGraphOperationStatus.OK;
1020     }
1021
1022     public Object getProperty(JanusGraphVertex vertex, String key) {
1023         PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key);
1024         return vertex.valueOrNull(propertyKey);
1025     }
1026
1027     public Object getProperty(Edge edge, EdgePropertyEnum key) {
1028         Object value = null;
1029         try {
1030             Property<Object> property = edge.property(key.getProperty());
1031             if (property != null) {
1032                 value = property.orElse(null);
1033                 if (value != null && key == EdgePropertyEnum.INSTANCES) {
1034                     return JsonParserUtils.toList((String) value, String.class);
1035                 }
1036                 return value;
1037             }
1038         } catch (Exception e) {
1039
1040         }
1041         return value;
1042     }
1043
1044     /**
1045      * 
1046      * @param vertexA
1047      * @param vertexB
1048      * @param label
1049      * @param direction
1050      * @return
1051      */
1052     public JanusGraphOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
1053         JanusGraphOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
1054         if (result != JanusGraphOperationStatus.OK) {
1055             logger.error("Failed to diassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
1056             return result;
1057         }
1058         JanusGraphOperationStatus createRelation;
1059         if (direction == Direction.IN) {
1060             createRelation = createEdge(vertexB, vertexA, label, null);
1061         } else {
1062             createRelation = createEdge(vertexA, vertexB, label, null);
1063         }
1064         if (createRelation != JanusGraphOperationStatus.OK) {
1065             return createRelation;
1066         }
1067         return JanusGraphOperationStatus.OK;
1068     }
1069
1070     public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label, Map<GraphPropertyEnum, Object> properties) {
1071         Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
1072         if (getVertexRes.isRight()) {
1073             return Either.right(getVertexRes.right().value());
1074         }
1075         return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);
1076     }
1077 }