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=========================================================
20 package org.openecomp.sdc.be.dao.janusgraph;
22 import static org.apache.commons.collections.CollectionUtils.isEmpty;
24 import fj.data.Either;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.Collections;
28 import java.util.EnumMap;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
33 import java.util.Map.Entry;
34 import java.util.Optional;
35 import java.util.function.Predicate;
36 import java.util.stream.Collectors;
37 import java.util.stream.StreamSupport;
39 import org.apache.commons.collections.MapUtils;
40 import org.apache.commons.collections4.CollectionUtils;
41 import org.apache.commons.lang.StringUtils;
42 import org.apache.commons.lang3.tuple.ImmutablePair;
43 import org.apache.tinkerpop.gremlin.structure.Direction;
44 import org.apache.tinkerpop.gremlin.structure.Edge;
45 import org.apache.tinkerpop.gremlin.structure.Element;
46 import org.apache.tinkerpop.gremlin.structure.Property;
47 import org.apache.tinkerpop.gremlin.structure.Vertex;
48 import org.apache.tinkerpop.gremlin.structure.util.ElementHelper;
49 import org.janusgraph.core.JanusGraph;
50 import org.janusgraph.core.JanusGraphEdge;
51 import org.janusgraph.core.JanusGraphQuery;
52 import org.janusgraph.core.JanusGraphVertex;
53 import org.janusgraph.core.JanusGraphVertexQuery;
54 import org.janusgraph.core.PropertyKey;
55 import org.janusgraph.graphdb.query.JanusGraphPredicate;
56 import org.openecomp.sdc.be.dao.api.exception.JanusGraphException;
57 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
58 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
59 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
60 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
61 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
62 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
63 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
64 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
65 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
66 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
67 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
68 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
69 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
70 import org.openecomp.sdc.common.log.enums.EcompLoggerErrorCode;
71 import org.openecomp.sdc.common.log.wrappers.Logger;
72 import org.springframework.beans.factory.annotation.Qualifier;
74 public class JanusGraphDao {
76 private static final Logger logger = Logger.getLogger(JanusGraphDao.class);
77 private static final String FAILED_TO_GET_BY_CRITERIA_FOR_TYPE_AND_PROPERTIES = "Failed to get by criteria for type '{}' and properties '{}'";
79 private final JanusGraphClient janusGraphClient;
81 public JanusGraphDao(@Qualifier("janusgraph-client") JanusGraphClient janusGraphClient) {
82 this.janusGraphClient = janusGraphClient;
83 logger.info("** JanusGraphDao created");
86 public JanusGraphOperationStatus commit() {
87 logger.debug("#commit - The operation succeeded. Doing commit...");
88 return janusGraphClient.commit();
91 public JanusGraphOperationStatus rollback() {
92 logger.debug("#rollback - The operation failed. Doing rollback...");
93 return janusGraphClient.rollback();
100 public Either<GraphVertex, JanusGraphOperationStatus> createVertex(GraphVertex graphVertex) {
101 logger.trace("try to create vertex for ID [{}]", graphVertex.getUniqueId());
102 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
103 if (graph.isLeft()) {
105 JanusGraph tGraph = graph.left().value();
106 JanusGraphVertex vertex = tGraph.addVertex();
107 setVertexProperties(vertex, graphVertex);
108 graphVertex.setVertex(vertex);
109 return Either.left(graphVertex);
110 } catch (Exception e) {
112 .error(EcompLoggerErrorCode.DATA_ERROR, "JanusGraphDao", "Failed to create Node for ID '{}'", (Object) graphVertex.getUniqueId(),
114 return Either.right(JanusGraphClient.handleJanusGraphException(e));
117 logger.debug("Failed to create vertex for ID '{}' {}", graphVertex.getUniqueId(), graph.right().value());
118 return Either.right(graph.right().value());
128 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label) {
129 return getVertexByPropertyAndLabel(name, value, label, JsonParseFlagEnum.ParseAll);
132 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByLabel(VertexTypeEnum label) {
133 return janusGraphClient.getGraph().left().map(graph -> graph.query().has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices())
134 .left().bind(janusGraphVertices -> getFirstFoundVertex(JsonParseFlagEnum.NoParse, janusGraphVertices));
137 private Either<GraphVertex, JanusGraphOperationStatus> getFirstFoundVertex(JsonParseFlagEnum parseFlag, Iterable<JanusGraphVertex> vertices) {
138 Iterator<JanusGraphVertex> iterator = vertices.iterator();
139 if (iterator.hasNext()) {
140 JanusGraphVertex vertex = iterator.next();
141 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
142 return Either.left(graphVertex);
144 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
154 public Either<GraphVertex, JanusGraphOperationStatus> getVertexByPropertyAndLabel(GraphPropertyEnum name, Object value, VertexTypeEnum label,
155 JsonParseFlagEnum parseFlag) {
156 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
157 if (graph.isLeft()) {
159 JanusGraph tGraph = graph.left().value();
160 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query().has(name.getProperty(), value)
161 .has(GraphPropertyEnum.LABEL.getProperty(), label.getName()).vertices();
162 java.util.Iterator<JanusGraphVertex> iterator = vertices.iterator();
163 if (iterator.hasNext()) {
164 JanusGraphVertex vertex = iterator.next();
165 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
166 return Either.left(graphVertex);
168 logger.debug("No vertex in graph for key = {} and value = {} label = {}", name, value, label);
169 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
170 } catch (Exception e) {
171 logger.debug("Failed to get vertex in graph for key ={} and value = {} label = {}", name, value, label);
172 return Either.right(JanusGraphClient.handleJanusGraphException(e));
175 logger.debug("No vertex in graph for key ={} and value = {} label = {} error :{}", name, value, label, graph.right().value());
176 return Either.right(graph.right().value());
184 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id) {
185 return getVertexById(id, JsonParseFlagEnum.ParseAll);
193 public Either<GraphVertex, JanusGraphOperationStatus> getVertexById(String id, JsonParseFlagEnum parseFlag) {
194 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
196 logger.debug("No vertex in graph for id = {} ", id);
197 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
199 if (graph.isLeft()) {
201 JanusGraph tGraph = graph.left().value();
202 @SuppressWarnings("unchecked") Iterable<JanusGraphVertex> vertices = tGraph.query()
203 .has(GraphPropertyEnum.UNIQUE_ID.getProperty(), id).vertices();
204 java.util.Iterator<JanusGraphVertex> iterator = vertices.iterator();
205 if (iterator.hasNext()) {
206 JanusGraphVertex vertex = iterator.next();
207 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
208 return Either.left(graphVertex);
210 logger.debug("No vertex in graph for id = {}", id);
211 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
213 } catch (Exception e) {
214 logger.debug("Failed to get vertex in graph for id {} ", id);
215 return Either.right(JanusGraphClient.handleJanusGraphException(e));
218 logger.debug("No vertex in graph for id {} error : {}", id, graph.right().value());
219 return Either.right(graph.right().value());
223 private void setVertexProperties(JanusGraphVertex vertex, GraphVertex graphVertex) throws IOException {
224 if (graphVertex.getMetadataProperties() != null) {
225 for (Map.Entry<GraphPropertyEnum, Object> entry : graphVertex.getMetadataProperties().entrySet()) {
226 if (entry.getValue() != null) {
227 vertex.property(entry.getKey().getProperty(), entry.getValue());
231 vertex.property(GraphPropertyEnum.LABEL.getProperty(), graphVertex.getLabel().getName());
232 Map<String, ? extends ToscaDataDefinition> json = graphVertex.getJson();
234 String jsonStr = JsonParserUtils.toJson(json);
235 vertex.property(GraphPropertyEnum.JSON.getProperty(), jsonStr);
237 Map<String, Object> jsonMetadata = graphVertex.getMetadataJson();
238 if (jsonMetadata != null) {
239 String jsonMetadataStr = JsonParserUtils.toJson(jsonMetadata);
240 vertex.property(GraphPropertyEnum.METADATA.getProperty(), jsonMetadataStr);
244 public void setVertexProperties(Vertex vertex, Map<String, Object> properties) {
245 for (Map.Entry<String, Object> entry : properties.entrySet()) {
246 if (entry.getValue() != null) {
247 vertex.property(entry.getKey(), entry.getValue());
252 private GraphVertex createAndFill(JanusGraphVertex vertex, JsonParseFlagEnum parseFlag) {
253 GraphVertex graphVertex = new GraphVertex();
254 graphVertex.setVertex(vertex);
255 parseVertexProperties(graphVertex, parseFlag);
259 public void parseVertexProperties(GraphVertex graphVertex, JsonParseFlagEnum parseFlag) {
260 JanusGraphVertex vertex = graphVertex.getVertex();
261 Map<GraphPropertyEnum, Object> properties = getVertexProperties(vertex);
262 VertexTypeEnum label = VertexTypeEnum.getByName((String) (properties.get(GraphPropertyEnum.LABEL)));
263 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
264 GraphPropertyEnum key = entry.getKey();
267 graphVertex.setUniqueId((String) entry.getValue());
270 graphVertex.setLabel(VertexTypeEnum.getByName((String) entry.getValue()));
273 String type = (String) entry.getValue();
275 graphVertex.setType(ComponentTypeEnum.valueOf(type));
279 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseJson) {
280 String json = (String) entry.getValue();
281 Map<String, ? extends ToscaDataDefinition> jsonObj = JsonParserUtils.toMap(json, label.getClassOfJson());
282 graphVertex.setJson(jsonObj);
286 if (parseFlag == JsonParseFlagEnum.ParseAll || parseFlag == JsonParseFlagEnum.ParseMetadata) {
287 String json = (String) entry.getValue();
288 Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
289 graphVertex.setMetadataJson(metadatObj);
293 graphVertex.addMetadataProperty(key, entry.getValue());
299 public JanusGraphOperationStatus createEdge(GraphVertex from, GraphVertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
300 return createEdge(from.getVertex(), to.getVertex(), label, properties);
303 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Map<EdgePropertyEnum, Object> properties) {
304 logger.trace("Try to connect {} with {} label {} properties {}",
305 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
306 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), label, properties);
307 if (from == null || to == null) {
308 logger.trace("No JanusGraph vertex for id from {} or id to {}",
309 from == null ? "NULL" : from.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
310 to == null ? "NULL" : to.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
311 return JanusGraphOperationStatus.NOT_FOUND;
313 Edge edge = from.addEdge(label.name(), to);
314 JanusGraphOperationStatus status;
316 setEdgeProperties(edge, properties);
317 status = JanusGraphOperationStatus.OK;
318 } catch (IOException e) {
319 logger.error(EcompLoggerErrorCode.DATA_ERROR, "JanusGraphDao", "Failed to set properties on edge properties [{}]", properties, e);
320 status = JanusGraphOperationStatus.GENERAL_ERROR;
325 public Map<GraphPropertyEnum, Object> getVertexProperties(Element element) {
326 Map<GraphPropertyEnum, Object> result = new HashMap<>();
327 if (element != null && CollectionUtils.isNotEmpty(element.keys())) {
328 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
329 for (Entry<String, Property> entry : propertyMap.entrySet()) {
330 String key = entry.getKey();
331 Object value = entry.getValue().value();
332 GraphPropertyEnum valueOf = GraphPropertyEnum.getByProperty(key);
333 if (valueOf != null) {
334 result.put(valueOf, value);
337 // add print to properties that can't be converted by enum
342 public Map<EdgePropertyEnum, Object> getEdgeProperties(Element element) {
343 Map<EdgePropertyEnum, Object> result = new HashMap<>();
344 if (element != null && CollectionUtils.isNotEmpty(element.keys())) {
345 Map<String, Property> propertyMap = ElementHelper.propertyMap(element, element.keys().toArray(new String[element.keys().size()]));
346 for (Entry<String, Property> entry : propertyMap.entrySet()) {
347 String key = entry.getKey();
348 Object value = entry.getValue().value();
349 EdgePropertyEnum valueOf = EdgePropertyEnum.getByProperty(key);
350 if (valueOf != null) {
351 if (valueOf == EdgePropertyEnum.INSTANCES) {
352 List<String> list = JsonParserUtils.toList((String) value, String.class);
353 result.put(valueOf, list);
355 result.put(valueOf, value);
363 public void setEdgeProperties(Element element, Map<EdgePropertyEnum, Object> properties) throws IOException {
364 if (properties != null && !properties.isEmpty()) {
365 Object[] propertyKeyValues = new Object[properties.size() * 2];
367 for (Entry<EdgePropertyEnum, Object> entry : properties.entrySet()) {
368 propertyKeyValues[i++] = entry.getKey().getProperty();
369 Object value = entry.getValue();
370 if (entry.getKey() == EdgePropertyEnum.INSTANCES) {
371 String jsonStr = JsonParserUtils.toJson(value);
372 propertyKeyValues[i++] = jsonStr;
374 propertyKeyValues[i++] = entry.getValue();
377 ElementHelper.attachProperties(element, propertyKeyValues);
381 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props) {
382 return getByCriteria(type, props, JsonParseFlagEnum.ParseAll);
385 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type, Map<GraphPropertyEnum, Object> props,
386 JsonParseFlagEnum parseFlag) {
387 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
388 if (graph.isLeft()) {
390 JanusGraph tGraph = graph.left().value();
391 JanusGraphQuery<? extends JanusGraphQuery> query = tGraph.query();
393 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
395 if (props != null && !props.isEmpty()) {
396 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
397 query = query.has(entry.getKey().getProperty(), entry.getValue());
400 Iterable<JanusGraphVertex> vertices = query.vertices();
401 if (vertices == null) {
402 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
404 Iterator<JanusGraphVertex> iterator = vertices.iterator();
405 List<GraphVertex> result = new ArrayList<>();
406 while (iterator.hasNext()) {
407 JanusGraphVertex vertex = iterator.next();
408 getVertexProperties(vertex);
409 GraphVertex graphVertex = createAndFill(vertex, parseFlag);
410 result.add(graphVertex);
412 logger.debug("Number of fetched nodes in graph for criteria : from type = {} and properties = {} is {}", type, props, result.size());
413 if (result.size() == 0) {
414 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
416 return Either.left(result);
417 } catch (Exception e) {
418 logger.debug("Failed get by criteria for type = {} and properties = {}", type, props, e);
419 return Either.right(JanusGraphClient.handleJanusGraphException(e));
422 logger.debug("Failed get by criteria for type ={} and properties = {} error : {}", type, props, graph.right().value());
423 return Either.right(graph.right().value());
427 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type, final Map<GraphPropertyEnum, Object> props,
428 final Map<GraphPropertyEnum, Object> hasNotProps,
429 final JsonParseFlagEnum parseFlag,
430 final String model) {
431 return getByCriteria(type, props, hasNotProps, null, parseFlag, model, false);
434 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type, final Map<GraphPropertyEnum, Object> props,
435 final Map<GraphPropertyEnum, Object> hasNotProps,
436 final JsonParseFlagEnum parseFlag,
438 final boolean includeNormativeExtensionModels) {
439 return getByCriteria(type, props, hasNotProps, null, parseFlag, model, includeNormativeExtensionModels);
442 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type,
443 final Map<GraphPropertyEnum, Object> hasProps,
444 final Map<GraphPropertyEnum, Object> hasNotProps,
445 final Map<String, Entry<JanusGraphPredicate, Object>> predicates,
446 final JsonParseFlagEnum parseFlag,
447 final String model) {
448 return getByCriteria(type, hasProps, hasNotProps, predicates, parseFlag, model, false);
451 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type,
452 final Map<GraphPropertyEnum, Object> hasProps,
453 final Map<GraphPropertyEnum, Object> hasNotProps,
454 final Map<String, Entry<JanusGraphPredicate, Object>> predicates,
455 final JsonParseFlagEnum parseFlag,
457 final boolean includeNormativeExtensionModels) {
458 Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
459 if (graph.isLeft()) {
461 JanusGraphQuery<? extends JanusGraphQuery> query = getJanusGraphQuery(type, hasProps, hasNotProps, predicates, graph.left().value());
462 final Iterable<JanusGraphVertex> vertices = query.vertices();
463 if (vertices == null || !vertices.iterator().hasNext()) {
464 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
467 final Predicate<? super JanusGraphVertex> filterPredicate = StringUtils.isEmpty(model) ? this::vertexNotConnectedToAnyModel
468 : vertex -> vertexValidForModel(vertex, model, includeNormativeExtensionModels);
469 final List<JanusGraphVertex> verticesForModel = StreamSupport.stream(vertices.spliterator(), false).filter(filterPredicate)
470 .collect(Collectors.toList());
471 if (CollectionUtils.isEmpty(verticesForModel)) {
472 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
475 final List<GraphVertex> result = new ArrayList<>();
476 verticesForModel.forEach(vertex -> result.add(createAndFill(vertex, parseFlag)));
477 logger.debug("Number of fetched nodes in graph for criteria : from type '{}' and properties '{}' is '{}'", type, hasProps,
479 return Either.left(result);
480 } catch (Exception e) {
481 logger.debug(FAILED_TO_GET_BY_CRITERIA_FOR_TYPE_AND_PROPERTIES, type, hasProps, e);
482 return Either.right(JanusGraphClient.handleJanusGraphException(e));
485 logger.debug("Failed to get by criteria for type '{}' and properties '{}'. Error : '{}'", type, hasProps, graph.right().value());
486 return Either.right(graph.right().value());
490 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(VertexTypeEnum type,
491 Map<GraphPropertyEnum, Object> props,
492 Map<GraphPropertyEnum, Object> hasNotProps,
493 JsonParseFlagEnum parseFlag) {
494 return getByCriteria(type, props, hasNotProps, null, parseFlag);
497 public Either<List<GraphVertex>, JanusGraphOperationStatus> getByCriteria(final VertexTypeEnum type,
498 final Map<GraphPropertyEnum, Object> hasProps,
499 final Map<GraphPropertyEnum, Object> hasNotProps,
500 final Map<String, Entry<JanusGraphPredicate, Object>> predicates,
501 final JsonParseFlagEnum parseFlag) {
502 final Either<JanusGraph, JanusGraphOperationStatus> graph = janusGraphClient.getGraph();
503 if (graph.isLeft()) {
505 JanusGraphQuery<? extends JanusGraphQuery> query = getJanusGraphQuery(type, hasProps, hasNotProps, predicates, graph.left().value());
506 Iterable<JanusGraphVertex> vertices = query.vertices();
507 if (vertices == null || !vertices.iterator().hasNext()) {
508 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
510 List<GraphVertex> result = new ArrayList<>();
511 vertices.forEach(vertex -> result.add(createAndFill(vertex, parseFlag)));
512 logger.debug("Number of fetched nodes in graph for criteria : from type '{}' and properties '{}' is '{}'", type, hasProps,
514 return Either.left(result);
515 } catch (Exception e) {
516 logger.debug(FAILED_TO_GET_BY_CRITERIA_FOR_TYPE_AND_PROPERTIES, type, hasProps, e);
517 return Either.right(JanusGraphClient.handleJanusGraphException(e));
520 logger.debug("Failed to get by criteria for type '{}' and properties '{}'. Error : '{}'", type, hasProps, graph.right().value());
521 return Either.right(graph.right().value());
526 * Finds the vertices that have the given invariant id and any additional property provided.
528 * @param invariantUuid the invariant uuid
529 * @param additionalPropertiesToMatch any additional property to match along with the {@link GraphPropertyEnum#INVARIANT_UUID}
530 * @return the list of vertex that has the given invariant uuid
531 * @throws JanusGraphException if the find operation was returned an error status
533 public List<GraphVertex> findAllVertexByInvariantUuid(final String invariantUuid,
534 final Map<GraphPropertyEnum, Object> additionalPropertiesToMatch) {
535 final Map<GraphPropertyEnum, Object> propertiesToMatch = new EnumMap<>(GraphPropertyEnum.class);
536 if (MapUtils.isNotEmpty(additionalPropertiesToMatch)) {
537 propertiesToMatch.putAll(additionalPropertiesToMatch);
539 propertiesToMatch.put(GraphPropertyEnum.INVARIANT_UUID, invariantUuid);
540 final Either<List<GraphVertex>, JanusGraphOperationStatus> vertexEither =
541 getByCriteria(null, propertiesToMatch, JsonParseFlagEnum.ParseMetadata);
542 if (vertexEither.isRight()) {
543 final JanusGraphOperationStatus status = vertexEither.right().value();
544 if (status == JanusGraphOperationStatus.NOT_FOUND) {
545 return Collections.emptyList();
547 final String errorMsg = String.format("Couldn't fetch vertex with invariantUUId '%s'. Status was '%s'", invariantUuid, status);
548 throw new JanusGraphException(status, errorMsg);
550 final List<GraphVertex> vertices = vertexEither.left().value();
551 if (vertices == null || vertices.isEmpty()) {
552 return Collections.emptyList();
557 private boolean vertexValidForModel(final JanusGraphVertex vertex, final String model, final boolean includeNormativeExtensions) {
558 final String vertexLabel = (String) vertex.property(GraphPropertyEnum.LABEL.getProperty()).value();
559 final VertexTypeEnum vertexType = VertexTypeEnum.getByName(vertexLabel);
560 final GraphEdgeLabels edgeLabel = VertexTypeEnum.TOPOLOGY_TEMPLATE.equals(vertexType) ? GraphEdgeLabels.MODEL : GraphEdgeLabels.MODEL_ELEMENT;
561 final Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> modelVertices = getParentVertices(vertex, edgeLabel);
563 return modelVertices.isLeft() && modelVertices.left().value().stream()
564 .anyMatch(vertexPair -> modelVertexMatchesModel(vertexPair.getLeft(), model, includeNormativeExtensions));
567 private boolean modelVertexMatchesModel(final JanusGraphVertex modelVertex, final String model, final boolean includeNormativeExtensions) {
568 if (model.equals((String) modelVertex.property("name").value())) {
571 final Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> derivedModels =
572 getParentVertices(modelVertex, GraphEdgeLabels.DERIVED_FROM);
573 if (derivedModels.isLeft() && derivedModels.left().value().stream()
574 .anyMatch(derivedModel -> modelVertexMatchesModel(derivedModel.left, model, includeNormativeExtensions))) {
578 if (includeNormativeExtensions && isANormativeExtension(modelVertex)) {
579 final Either<List<Vertex>, JanusGraphOperationStatus> derivedFromModels =
580 getChildrenVertices(modelVertex, EdgeLabelEnum.DERIVED_FROM);
581 return derivedFromModels.isLeft() && derivedFromModels.left().value().stream()
582 .anyMatch(derivedFromModel -> model.equals((String) derivedFromModel.property("name").value()));
587 private boolean isANormativeExtension(final JanusGraphVertex modelVertex) {
588 return ModelTypeEnum.NORMATIVE_EXTENSION.getValue().equals((String) modelVertex.property(GraphPropertyEnum.MODEL_TYPE.getProperty()).value());
591 private Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getParentVertices(
592 final JanusGraphVertex rootVertex, final GraphEdgeLabels edgeType) {
593 return getEdgeVertices(rootVertex, Direction.IN, edgeType);
596 private Either<List<ImmutablePair<JanusGraphVertex, Edge>>, JanusGraphOperationStatus> getEdgeVertices(
597 final JanusGraphVertex rootVertex, final Direction direction, final GraphEdgeLabels edgeType) {
598 final List<ImmutablePair<JanusGraphVertex, Edge>> immutablePairs = new ArrayList<>();
599 final Iterator<Edge> edgesCreatorIterator = rootVertex.edges(direction, edgeType.getProperty());
600 if (edgesCreatorIterator != null) {
601 while (edgesCreatorIterator.hasNext()) {
602 Edge edge = edgesCreatorIterator.next();
603 JanusGraphVertex vertex = Direction.OUT.equals(direction) ? (JanusGraphVertex) edge.inVertex() : (JanusGraphVertex) edge.outVertex();
604 ImmutablePair<JanusGraphVertex, Edge> immutablePair = new ImmutablePair<>(vertex, edge);
605 immutablePairs.add(immutablePair);
608 if (immutablePairs.isEmpty()) {
609 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
611 return Either.left(immutablePairs);
614 private boolean vertexNotConnectedToAnyModel(final JanusGraphVertex vertex) {
615 String vt = (String) vertex.property(GraphPropertyEnum.LABEL.getProperty()).value();
616 VertexTypeEnum vertexType = VertexTypeEnum.getByName(vt);
617 EdgeLabelEnum edgeLabel = VertexTypeEnum.TOPOLOGY_TEMPLATE.equals(vertexType) ? EdgeLabelEnum.MODEL : EdgeLabelEnum.MODEL_ELEMENT;
618 return !vertex.edges(Direction.IN, edgeLabel.name()).hasNext();
621 public Either<Iterator<Vertex>, JanusGraphOperationStatus> getCatalogOrArchiveVertices(boolean isCatalog) {
622 Either<JanusGraph, JanusGraphOperationStatus> graphEither = janusGraphClient.getGraph();
623 if (graphEither.isLeft()) {
625 JanusGraph graph = graphEither.left().value();
626 String vertexType = isCatalog ? VertexTypeEnum.CATALOG_ROOT.getName() : VertexTypeEnum.ARCHIVE_ROOT.getName();
627 Iterable<JanusGraphVertex> vertexIterable = graph.query().has(GraphPropertyEnum.LABEL.getProperty(), vertexType).vertices();
628 if (vertexIterable == null) {
629 logger.debug("Failed to fetch catalog vertex");
630 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
632 JanusGraphVertex catalogVertex = vertexIterable.iterator().next();
633 if (catalogVertex == null) {
634 logger.debug("Failed to fetch catalog vertex");
635 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
637 String edgeLabel = isCatalog ? EdgeLabelEnum.CATALOG_ELEMENT.name() : EdgeLabelEnum.ARCHIVE_ELEMENT.name();
638 Iterator<Vertex> adjacentVertices = catalogVertex.vertices(Direction.OUT, edgeLabel);
639 return Either.left(adjacentVertices);
640 } catch (Exception e) {
641 logger.debug("Failed get by criteria: ", e);
642 return Either.right(JanusGraphClient.handleJanusGraphException(e));
645 logger.debug("Failed get by criteria : {}", graphEither.right().value());
646 return Either.right(graphEither.right().value());
650 private void buildMultipleNegateQueryFromList(Map.Entry<GraphPropertyEnum, Object> entry, JanusGraphQuery query) {
651 for (Object listItem : (List<Object>) entry.getValue()) {
652 query.hasNot(entry.getKey().getProperty(), listItem);
657 * @param parentVertex
662 public Either<GraphVertex, JanusGraphOperationStatus> getChildVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel,
663 JsonParseFlagEnum parseFlag) {
664 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertices = getChildrenVertices(parentVertex, edgeLabel, parseFlag);
665 if (childrenVertices.isRight()) {
666 return Either.right(childrenVertices.right().value());
668 return Either.left(childrenVertices.left().value().get(0));
672 * @param parentVertex
676 public Either<Vertex, JanusGraphOperationStatus> getChildVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel) {
677 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertices = getChildrenVertices(parentVertex, edgeLabel);
678 if (childrenVertices.isRight()) {
679 return Either.right(childrenVertices.right().value());
681 return Either.left(childrenVertices.left().value().get(0));
684 public Either<GraphVertex, JanusGraphOperationStatus> getParentVertex(GraphVertex parentVertex, EdgeLabelEnum edgeLabel,
685 JsonParseFlagEnum parseFlag) {
686 Either<List<GraphVertex>, JanusGraphOperationStatus> childrenVertices = getParentVertices(parentVertex, edgeLabel, parseFlag);
687 if (childrenVertices.isRight()) {
688 return Either.right(childrenVertices.right().value());
690 if (isEmpty(childrenVertices.left().value())) {
691 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
693 return Either.left(childrenVertices.left().value().get(0));
696 public Either<Vertex, JanusGraphOperationStatus> getParentVertex(Vertex parentVertex, EdgeLabelEnum edgeLabel) {
697 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertices = getParentVertices(parentVertex, edgeLabel);
698 if (childrenVertices.isRight()) {
699 return Either.right(childrenVertices.right().value());
701 if (isEmpty(childrenVertices.left().value())) {
702 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
704 return Either.left(childrenVertices.left().value().get(0));
708 * @param parentVertex
713 public Either<List<GraphVertex>, JanusGraphOperationStatus> getChildrenVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel,
714 JsonParseFlagEnum parseFlag) {
715 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.OUT);
718 public Either<List<GraphVertex>, JanusGraphOperationStatus> getParentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel,
719 JsonParseFlagEnum parseFlag) {
720 return getAdjacentVertices(parentVertex, edgeLabel, parseFlag, Direction.IN);
723 public Either<List<Vertex>, JanusGraphOperationStatus> getParentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel) {
724 return getAdjacentVertices(parentVertex, edgeLabel, Direction.IN);
727 private Either<List<Vertex>, JanusGraphOperationStatus> getAdjacentVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel, Direction direction) {
728 List<Vertex> list = new ArrayList<>();
730 Either<JanusGraph, JanusGraphOperationStatus> graphRes = janusGraphClient.getGraph();
731 if (graphRes.isRight()) {
732 logger.error("Failed to retrieve graph. status is {}", graphRes);
733 return Either.right(graphRes.right().value());
735 Iterator<Edge> edgesCreatorIterator = parentVertex.edges(direction, edgeLabel.name());
736 if (edgesCreatorIterator != null) {
737 while (edgesCreatorIterator.hasNext()) {
738 Edge edge = edgesCreatorIterator.next();
739 JanusGraphVertex vertex;
740 if (direction == Direction.IN) {
741 vertex = (JanusGraphVertex) edge.outVertex();
743 vertex = (JanusGraphVertex) edge.inVertex();
748 if (list.isEmpty()) {
749 return Either.right(JanusGraphOperationStatus.NOT_FOUND);
751 } catch (Exception e) {
752 logger.error("Failed to perform graph operation ", e);
753 Either.right(JanusGraphClient.handleJanusGraphException(e));
755 return Either.left(list);
759 * @param parentVertex
763 public Either<List<Vertex>, JanusGraphOperationStatus> getChildrenVertices(Vertex parentVertex, EdgeLabelEnum edgeLabel) {
764 return getAdjacentVertices(parentVertex, edgeLabel, Direction.OUT);
767 private Either<List<GraphVertex>, JanusGraphOperationStatus> getAdjacentVertices(GraphVertex parentVertex, EdgeLabelEnum edgeLabel,
768 JsonParseFlagEnum parseFlag, Direction direction) {
769 List<GraphVertex> list = new ArrayList<>();
770 Either<List<Vertex>, JanusGraphOperationStatus> adjacentVertices = getAdjacentVertices(parentVertex.getVertex(), edgeLabel,
772 if (adjacentVertices.isRight()) {
773 return Either.right(adjacentVertices.right().value());
775 adjacentVertices.left().value().stream().forEach(vertex -> list.add(createAndFill((JanusGraphVertex) vertex, parseFlag)));
776 return Either.left(list);
780 * Searches Edge by received label and criteria
785 * @return found edge or JanusGraphOperationStatus
787 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label,
788 Map<GraphPropertyEnum, Object> properties) {
789 Either<Edge, JanusGraphOperationStatus> result = null;
790 Edge matchingEdge = null;
791 String notFoundMsg = "No edges in graph for criteria";
793 JanusGraphVertexQuery<?> query = vertex.getVertex().query().labels(label.name());
794 if (properties != null && !properties.isEmpty()) {
795 for (Map.Entry<GraphPropertyEnum, Object> entry : properties.entrySet()) {
796 query = query.has(entry.getKey().getProperty(), entry.getValue());
799 Iterable<JanusGraphEdge> edges = query.edges();
801 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
802 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
804 Iterator<JanusGraphEdge> eIter = edges.iterator();
805 if (eIter.hasNext()) {
806 matchingEdge = eIter.next();
808 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
809 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
812 if (result == null) {
813 result = Either.left(matchingEdge);
815 } catch (Exception e) {
816 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}",
817 vertex.getUniqueId(), e);
818 return Either.right(JanusGraphClient.handleJanusGraphException(e));
823 public Either<Edge, JanusGraphOperationStatus> getEdgeByChildrenVertexProperties(GraphVertex vertex, EdgeLabelEnum label,
824 Map<GraphPropertyEnum, Object> properties) {
825 Either<Edge, JanusGraphOperationStatus> result = null;
826 Edge matchingEdge = null;
827 String notFoundMsg = "No edges in graph for criteria";
829 Iterator<Edge> edges = vertex.getVertex().edges(Direction.OUT, label.name());
830 while (edges.hasNext()) {
831 matchingEdge = edges.next();
832 Vertex childV = matchingEdge.inVertex();
833 Map<GraphPropertyEnum, Object> vertexProperties = getVertexProperties(childV);
834 Optional<Entry<GraphPropertyEnum, Object>> findNotMatch = properties.entrySet().stream()
835 .filter(e -> vertexProperties.get(e.getKey()) == null || !vertexProperties.get(e.getKey()).equals(e.getValue())).findFirst();
836 if (!findNotMatch.isPresent()) {
837 result = Either.left(matchingEdge);
840 if (result == null) {
842 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, notFoundMsg);
843 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
845 } catch (Exception e) {
846 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during getting edge by criteria for component with id {}. {}",
847 vertex.getUniqueId(), e);
848 return Either.right(JanusGraphClient.handleJanusGraphException(e));
854 * Deletes Edge by received label and criteria
861 public Either<Edge, JanusGraphOperationStatus> deleteBelongingEdgeByCriteria(GraphVertex vertex, EdgeLabelEnum label,
862 Map<GraphPropertyEnum, Object> properties) {
863 Either<Edge, JanusGraphOperationStatus> result = null;
865 result = getBelongingEdgeByCriteria(vertex, label, properties);
866 if (result.isLeft()) {
867 Edge edge = result.left().value();
869 .addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} belonging to the vertex {} ", label.name(),
870 vertex.getUniqueId());
872 result = Either.left(edge);
875 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find an edge with the label {} belonging to the vertex {} ", label.name(),
876 vertex.getUniqueId());
878 } catch (Exception e) {
880 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleting an edge by criteria for the component with id {}. {}",
881 vertex == null ? "NULL" : vertex.getUniqueId(), e);
882 return Either.right(JanusGraphClient.handleJanusGraphException(e));
887 @SuppressWarnings("unchecked")
889 * Deletes an edge between vertices fromVertex and toVertex according to received label
896 public Either<Edge, JanusGraphOperationStatus> deleteEdge(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
897 return deleteEdge(fromVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), false);
900 public Either<Edge, JanusGraphOperationStatus> deleteAllEdges(GraphVertex fromVertex, GraphVertex toVertex, EdgeLabelEnum label) {
901 return deleteEdge(fromVertex.getVertex(), label, fromVertex.getUniqueId(), toVertex.getUniqueId(), true);
904 private Either<Edge, JanusGraphOperationStatus> deleteEdge(JanusGraphVertex fromVertex, EdgeLabelEnum label,
905 String uniqueIdFrom, String uniqueIdTo, boolean deleteAll) {
906 Either<Edge, JanusGraphOperationStatus> result = null;
907 Vertex problemV = null;
909 Iterable<JanusGraphEdge> edges = fromVertex.query().labels(label.name()).edges();
910 Iterator<JanusGraphEdge> eIter = edges.iterator();
911 while (eIter.hasNext()) {
912 Edge edge = eIter.next();
913 problemV = edge.inVertex();
914 String currVertexUniqueId = null;
916 currVertexUniqueId = edge.inVertex().value(GraphPropertyEnum.UNIQUE_ID.getProperty());
917 } catch (Exception e) {
918 // AutoHealing procedure
919 logger.info("Corrupted vertex and edge were found and deleted ", e);
920 if (problemV != null) {
921 Map<GraphPropertyEnum, Object> props = getVertexProperties(problemV);
922 logger.debug("problematic Vertex properties:");
923 logger.debug("props size: {}", props.size());
924 for (Map.Entry<GraphPropertyEnum, Object> entry : props.entrySet()) {
925 logger.debug("{}:{}", entry.getKey(), entry.getValue());
927 Either<List<Vertex>, JanusGraphOperationStatus> childrenVertices = getChildrenVertices(problemV, EdgeLabelEnum.VERSION);
928 if (childrenVertices.isLeft()) {
929 childrenVertices.left().value().size();
930 logger.debug("number of children that problematic Vertex has: {}", props.size());
934 } catch (Exception e1) {
935 logger.debug("failed to remove problematic edge.", e1);
939 } catch (Exception e2) {
940 logger.debug("failed to remove problematic vertex.", e2);
945 if (currVertexUniqueId != null && currVertexUniqueId.equals(uniqueIdTo)) {
946 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to delete an edge with the label {} between vertices {} and {}. ",
947 label.name(), uniqueIdFrom, uniqueIdTo);
949 result = Either.left(edge);
955 if (result == null) {
956 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete an edge with the label {} between vertices {} and {}. ",
957 label.name(), uniqueIdFrom, uniqueIdTo);
958 result = Either.right(JanusGraphOperationStatus.NOT_FOUND);
960 } catch (Exception e) {
961 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
962 "Exception occured during deleting an edge with the label {} between vertices {} and {}. {}", label.name(), uniqueIdFrom, uniqueIdTo,
964 return Either.right(JanusGraphClient.handleJanusGraphException(e));
969 public JanusGraphOperationStatus deleteEdgeByDirection(GraphVertex fromVertex, Direction direction, EdgeLabelEnum label) {
971 Iterator<Edge> edges = fromVertex.getVertex().edges(direction, label.name());
972 while (edges.hasNext()) {
973 Edge edge = edges.next();
976 } catch (Exception e) {
977 logger.debug("Failed to remove from vertex {} edges {} by direction {} ", fromVertex.getUniqueId(), label, direction, e);
978 return JanusGraphClient.handleJanusGraphException(e);
980 return JanusGraphOperationStatus.OK;
984 * Updates vertex properties. Note that graphVertex argument should contain updated data
989 public Either<GraphVertex, JanusGraphOperationStatus> updateVertex(GraphVertex graphVertex) {
990 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId());
992 graphVertex.updateMetadataJsonWithCurrentMetadataProperties();
993 setVertexProperties(graphVertex.getVertex(), graphVertex);
994 } catch (Exception e) {
996 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update metadata of vertex with uniqueId {}. ", graphVertex.getUniqueId(), e);
997 return Either.right(JanusGraphClient.handleJanusGraphException(e));
999 return Either.left(graphVertex);
1003 * Fetches vertices by uniqueId according to received parse flag
1005 * @param verticesToGet
1008 public Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesByUniqueIdAndParseFlag(
1009 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGet) {
1010 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> result = null;
1011 Map<String, GraphVertex> vertices = new HashMap<>();
1012 JanusGraphOperationStatus titatStatus;
1013 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = null;
1014 for (Map.Entry<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> entry : verticesToGet.entrySet()) {
1015 if (entry.getValue().getKey() == GraphPropertyEnum.UNIQUE_ID) {
1016 getVertexRes = getVertexById(entry.getKey(), entry.getValue().getValue());
1017 } else if (entry.getValue().getKey() == GraphPropertyEnum.USERID) {
1018 getVertexRes = getVertexByPropertyAndLabel(entry.getValue().getKey(), entry.getKey(), VertexTypeEnum.USER,
1019 entry.getValue().getValue());
1021 if (getVertexRes == null) {
1022 titatStatus = JanusGraphOperationStatus.ILLEGAL_ARGUMENT;
1024 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Invalid vertex type label {} has been received. ", entry.getValue().getKey(),
1026 return Either.right(titatStatus);
1028 if (getVertexRes.isRight()) {
1029 titatStatus = getVertexRes.right().value();
1031 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get vertex by id {} . Status is {}. ", entry.getKey(), titatStatus);
1032 result = Either.right(titatStatus);
1035 vertices.put(entry.getKey(), getVertexRes.left().value());
1038 if (result == null) {
1039 result = Either.left(vertices);
1045 * Creates edge between "from" and "to" vertices with specified label and properties extracted from received edge
1053 public JanusGraphOperationStatus createEdge(Vertex from, Vertex to, EdgeLabelEnum label, Edge edgeToCopy) {
1054 return createEdge(from, to, label, getEdgeProperties(edgeToCopy));
1057 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, Edge prevEdge, EdgeLabelEnum prevLabel,
1058 EdgeLabelEnum newLabel) {
1060 .addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to {} between vertices {} and {}", prevLabel, newLabel,
1061 fromVertex != null ? fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL",
1062 toVertex != null ? toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()) : "NULL");
1063 JanusGraphOperationStatus result = createEdge(fromVertex, toVertex, newLabel, prevEdge);
1064 if (result == JanusGraphOperationStatus.OK) {
1071 * Replaces previous label of edge with new label
1079 public JanusGraphOperationStatus replaceEdgeLabel(Vertex fromVertex, Vertex toVertex, EdgeLabelEnum prevLabel, EdgeLabelEnum newLabel) {
1080 Iterator<Edge> prevEdgeIter = toVertex.edges(Direction.IN, prevLabel.name());
1081 if (prevEdgeIter == null || !prevEdgeIter.hasNext()) {
1083 .addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace edge with label {} to {} between vertices {} and {}", prevLabel,
1084 newLabel, fromVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
1085 toVertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()));
1086 return JanusGraphOperationStatus.NOT_FOUND;
1088 return replaceEdgeLabel(fromVertex, toVertex, prevEdgeIter.next(), prevLabel, newLabel);
1093 * Updates metadata properties of vertex on graph. Json metadata property of the vertex will be updated with received properties too.
1099 public JanusGraphOperationStatus updateVertexMetadataPropertiesWithJson(Vertex vertex, Map<GraphPropertyEnum, Object> properties) {
1101 if (!MapUtils.isEmpty(properties)) {
1102 String jsonMetadataStr = (String) vertex.property(GraphPropertyEnum.METADATA.getProperty()).value();
1103 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap(jsonMetadataStr);
1104 for (Map.Entry<GraphPropertyEnum, Object> property : properties.entrySet()) {
1105 vertex.property(property.getKey().getProperty(), property.getValue());
1106 jsonMetadataMap.put(property.getKey().getProperty(), property.getValue());
1108 vertex.property(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
1110 } catch (Exception e) {
1111 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occurred during update vertex metadata properties with json{}. {}",
1112 vertex.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), e.getMessage());
1113 return JanusGraphClient.handleJanusGraphException(e);
1115 return JanusGraphOperationStatus.OK;
1118 public JanusGraphOperationStatus disassociateAndDeleteLast(GraphVertex vertex, Direction direction, EdgeLabelEnum label) {
1120 Iterator<Edge> edges = vertex.getVertex().edges(direction, label.name());
1121 while (edges.hasNext()) {
1122 Edge edge = edges.next();
1123 Vertex secondVertex;
1124 Direction reverseDirection;
1125 if (direction == Direction.IN) {
1126 secondVertex = edge.outVertex();
1127 reverseDirection = Direction.OUT;
1129 secondVertex = edge.inVertex();
1130 reverseDirection = Direction.IN;
1133 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Edge {} with direction {} was removed from {}", label.name(), direction,
1134 vertex.getVertex());
1135 Iterator<Edge> restOfEdges = secondVertex.edges(reverseDirection, label.name());
1136 if (!restOfEdges.hasNext()) {
1137 secondVertex.remove();
1138 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "This was last edge . Vertex {} was removed ", vertex.getUniqueId());
1141 } catch (Exception e) {
1142 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
1143 "Exception occured during deleting an edge with the label {} direction {} from vertex {}. {}", label.name(), direction,
1144 vertex.getUniqueId(), e);
1145 return JanusGraphClient.handleJanusGraphException(e);
1147 return JanusGraphOperationStatus.OK;
1150 public Object getProperty(JanusGraphVertex vertex, String key) {
1151 PropertyKey propertyKey = janusGraphClient.getGraph().left().value().getPropertyKey(key);
1152 return vertex.valueOrNull(propertyKey);
1155 public Object getProperty(Edge edge, EdgePropertyEnum key) {
1156 Object value = null;
1158 Property<Object> property = edge.property(key.getProperty());
1159 if (property != null) {
1160 value = property.orElse(null);
1161 if (value != null && key == EdgePropertyEnum.INSTANCES) {
1162 return JsonParserUtils.toList((String) value, String.class);
1166 } catch (Exception e) {
1178 public JanusGraphOperationStatus moveEdge(GraphVertex vertexA, GraphVertex vertexB, EdgeLabelEnum label, Direction direction) {
1179 JanusGraphOperationStatus result = deleteEdgeByDirection(vertexA, direction, label);
1180 if (result != JanusGraphOperationStatus.OK) {
1181 logger.error("Failed to disassociate {} from element {}. error {} ", label, vertexA.getUniqueId(), result);
1184 JanusGraphOperationStatus createRelation;
1185 if (direction == Direction.IN) {
1186 createRelation = createEdge(vertexB, vertexA, label, null);
1188 createRelation = createEdge(vertexA, vertexB, label, null);
1190 if (createRelation != JanusGraphOperationStatus.OK) {
1191 return createRelation;
1193 return JanusGraphOperationStatus.OK;
1196 public Either<Edge, JanusGraphOperationStatus> getBelongingEdgeByCriteria(String parentId, EdgeLabelEnum label,
1197 Map<GraphPropertyEnum, Object> properties) {
1198 Either<GraphVertex, JanusGraphOperationStatus> getVertexRes = getVertexById(parentId, JsonParseFlagEnum.NoParse);
1199 if (getVertexRes.isRight()) {
1200 return Either.right(getVertexRes.right().value());
1202 return getBelongingEdgeByCriteria(getVertexRes.left().value(), label, properties);
1205 private JanusGraphQuery<? extends JanusGraphQuery> getJanusGraphQuery(final VertexTypeEnum type, final Map<GraphPropertyEnum, Object> hasProps,
1206 final Map<GraphPropertyEnum, Object> hasNotProps,
1207 final Map<String, Entry<JanusGraphPredicate, Object>> predicates,
1208 final JanusGraph graph) {
1209 JanusGraphQuery<? extends JanusGraphQuery> query = graph.query();
1212 query = query.has(GraphPropertyEnum.LABEL.getProperty(), type.getName());
1214 if (hasProps != null && !hasProps.isEmpty()) {
1215 for (Entry<GraphPropertyEnum, Object> entry : hasProps.entrySet()) {
1216 query = query.has(entry.getKey().getProperty(), entry.getValue());
1219 if (hasNotProps != null && !hasNotProps.isEmpty()) {
1220 for (Entry<GraphPropertyEnum, Object> entry : hasNotProps.entrySet()) {
1221 if (entry.getValue() instanceof List) {
1222 buildMultipleNegateQueryFromList(entry, query);
1224 query = query.hasNot(entry.getKey().getProperty(), entry.getValue());
1228 if (predicates != null && !predicates.isEmpty()) {
1229 for (Entry<String, Entry<JanusGraphPredicate, Object>> entry : predicates.entrySet()) {
1230 query = query.has(entry.getKey(), entry.getValue().getKey(), entry.getValue().getValue());