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.model.jsonjanusgraph.operations;
22 import fj.data.Either;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
29 import java.util.UUID;
30 import java.util.stream.Collectors;
31 import org.apache.commons.collections.CollectionUtils;
32 import org.apache.commons.collections.MapUtils;
33 import org.apache.commons.lang3.StringUtils;
34 import org.apache.commons.lang3.tuple.ImmutablePair;
35 import org.apache.commons.lang3.tuple.Pair;
36 import org.apache.tinkerpop.gremlin.structure.Direction;
37 import org.apache.tinkerpop.gremlin.structure.Edge;
38 import org.apache.tinkerpop.gremlin.structure.Vertex;
39 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
40 import org.janusgraph.core.JanusGraphVertex;
41 import org.openecomp.sdc.be.dao.impl.HealingPipelineDao;
42 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
43 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
44 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
45 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
46 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
47 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
48 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
49 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
55 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
56 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
57 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
58 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
59 import org.openecomp.sdc.be.model.User;
60 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
61 import org.openecomp.sdc.be.model.operations.StorageException;
62 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
63 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
64 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
65 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
66 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
67 import org.openecomp.sdc.common.log.wrappers.Logger;
68 import org.openecomp.sdc.common.util.ValidationUtils;
69 import org.springframework.beans.factory.annotation.Autowired;
72 * public abstract class BaseOperation provides base operation functionality and common fields
74 public abstract class BaseOperation {
76 public static final String VF_MODULE = "org.openecomp.groups.VfModule";
77 private static final String FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS = "Failed remove tosca data vertex of the tosca element {} by label {}. Status is {}. ";
78 private static final String FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS = "Failed to get child vertex of the tosca element {} by label {}. Status is {}. ";
79 private static final String FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS = "Failed to get tosca element {} upon adding the properties. Status is {}. ";
80 private static final Logger log = Logger.getLogger(BaseOperation.class.getName());
82 protected JanusGraphDao janusGraphDao;
84 protected NodeTypeOperation nodeTypeOperation;
86 protected TopologyTemplateOperation topologyTemplateOperation;
88 protected HealingPipelineDao healingPipelineDao;
90 public void setJanusGraphDao(JanusGraphDao janusGraphDao) {
91 this.janusGraphDao = janusGraphDao;
95 * Returns reference to appropriate toscaTemplateOperation
97 * @param componentType
100 public ToscaElementOperation getToscaElementOperation(ComponentTypeEnum componentType) {
101 ToscaElementOperation operation;
102 switch (componentType) {
105 operation = topologyTemplateOperation;
108 operation = nodeTypeOperation;
115 * Returns reference to appropriate toscaTemplateOperation
117 * @param toscaElementType
120 public ToscaElementOperation getToscaElementOperation(ToscaElementTypeEnum toscaElementType) {
121 ToscaElementOperation operation;
122 switch (toscaElementType) {
123 case TOPOLOGY_TEMPLATE:
124 operation = topologyTemplateOperation;
127 operation = nodeTypeOperation;
137 * Returns reference to appropriate toscaTemplateOperation
139 * @param toscaElementType
142 public ToscaElementOperation getToscaElementOperation(VertexTypeEnum toscaElementType) {
143 ToscaElementOperation operation;
144 switch (toscaElementType) {
145 case TOPOLOGY_TEMPLATE:
146 operation = topologyTemplateOperation;
149 operation = nodeTypeOperation;
159 * Converts received vertex to User object
164 public User convertToUser(Vertex ownerV) {
165 User owner = new User();
166 owner.setUserId((String) ownerV.property(GraphPropertyEnum.USERID.getProperty()).value());
167 VertexProperty<Object> property = ownerV.property(GraphPropertyEnum.ROLE.getProperty());
168 if (property != null && property.isPresent()) {
169 owner.setRole((String) property.value());
171 property = ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty());
172 if (property != null && property.isPresent()) {
173 owner.setFirstName((String) ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty()).value());
175 property = ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty());
176 if (property != null && property.isPresent()) {
177 owner.setLastName((String) ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty()).value());
179 property = ownerV.property(GraphPropertyEnum.EMAIL.getProperty());
180 if (property != null && property.isPresent()) {
181 owner.setEmail((String) ownerV.property(GraphPropertyEnum.EMAIL.getProperty()).value());
183 property = ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty());
184 if (property != null && property.isPresent()) {
185 owner.setLastLoginTime((Long) ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty()).value());
190 protected <T extends ToscaDataDefinition> Either<Map<String, T>, JanusGraphOperationStatus> getDataFromGraph(GraphVertex componentV,
191 EdgeLabelEnum edgelabel) {
192 Either<Pair<GraphVertex, Map<String, T>>, JanusGraphOperationStatus> dataVertex = getDataAndVertexFromGraph(componentV, edgelabel);
193 if (dataVertex.isRight()) {
194 return Either.right(dataVertex.right().value());
196 Map<String, T> properties = dataVertex.left().value().getRight();
197 return Either.left(properties);
200 @SuppressWarnings("unchecked")
201 protected <T extends ToscaDataDefinition> Either<Pair<GraphVertex, Map<String, T>>, JanusGraphOperationStatus> getDataAndVertexFromGraph(
202 GraphVertex componentV, EdgeLabelEnum edgelabel) {
203 Either<GraphVertex, JanusGraphOperationStatus> dataVertex = getDataVertex(componentV, edgelabel);
204 if (dataVertex.isRight()) {
205 return Either.right(dataVertex.right().value());
207 GraphVertex propV = dataVertex.left().value();
208 Map<String, T> properties = (Map<String, T>) propV.getJson();
209 Pair<GraphVertex, Map<String, T>> pair = new ImmutablePair<>(propV, properties);
210 return Either.left(pair);
213 protected <T extends ToscaDataDefinition> Either<GraphVertex, JanusGraphOperationStatus> getDataVertex(GraphVertex componentV,
214 EdgeLabelEnum edgelabel) {
215 Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao.getChildVertex(componentV, edgelabel, JsonParseFlagEnum.ParseJson);
216 if (childVertex.isRight()) {
217 if (childVertex.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
218 log.debug("failed to fetch {} for tosca element with id {}, error {}", edgelabel, componentV.getUniqueId(),
219 childVertex.right().value());
221 return Either.right(childVertex.right().value());
223 GraphVertex propV = childVertex.left().value();
224 return Either.left(propV);
228 * Returns tosca data belonging to tosca element specified by uid according received label
230 * @param toscaElementUid
234 public <T extends ToscaDataDefinition> Either<Map<String, T>, JanusGraphOperationStatus> getDataFromGraph(String toscaElementUid,
235 EdgeLabelEnum edgelabel) {
236 Either<Map<String, T>, JanusGraphOperationStatus> result = null;
237 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
238 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
239 if (getToscaElementRes.isRight()) {
240 JanusGraphOperationStatus status = getToscaElementRes.right().value();
241 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ",
242 toscaElementUid, status);
243 result = Either.right(status);
245 if (result == null) {
246 result = getDataFromGraph(getToscaElementRes.left().value(), edgelabel);
251 public Either<GraphVertex, JanusGraphOperationStatus> findUserVertex(String userId) {
252 return janusGraphDao.getVertexByPropertyAndLabel(GraphPropertyEnum.USERID, userId, VertexTypeEnum.USER, JsonParseFlagEnum.NoParse);
260 public Either<Boolean, StorageOperationStatus> isCloneNeeded(String elemementId, EdgeLabelEnum label) {
261 Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(elemementId);
262 if (vertexById.isRight()) {
263 log.debug("Failed to fetch element by id {} error {}", elemementId, vertexById.right().value());
264 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value()));
266 GraphVertex toscaElementVertex = vertexById.left().value();
267 Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
268 .getChildVertex(toscaElementVertex, label, JsonParseFlagEnum.NoParse);
269 if (childVertex.isRight()) {
270 if (childVertex.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
271 log.debug("failed to fetch {} for tosca element with id {}, error {}", label, toscaElementVertex.getUniqueId(),
272 childVertex.right().value());
273 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(childVertex.right().value()));
275 return Either.left(Boolean.FALSE);
277 GraphVertex dataVertex = childVertex.left().value();
278 Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
280 while (edges.hasNext()) {
285 return Either.left(Boolean.TRUE);
287 return Either.left(Boolean.FALSE);
291 protected Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyOnUpdate(GraphVertex dataVertex, GraphVertex toscaElementVertex,
292 EdgeLabelEnum label) {
293 Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
295 Edge edgeToRemove = null;
296 while (edges.hasNext()) {
297 Edge edge = edges.next();
299 Vertex outVertex = edge.outVertex();
300 String outId = (String) janusGraphDao.getProperty((JanusGraphVertex) outVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
301 if (toscaElementVertex.getUniqueId().equals(outId)) {
305 if (edgeToRemove == null) {
306 log.debug("No edges {} from vertex {} to vertex {}", label, toscaElementVertex.getUniqueId(), dataVertex.getUniqueId());
307 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
312 log.debug("No edges {} to vertex {}", label, dataVertex.getUniqueId());
313 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
316 log.trace("Only one edge {} to vertex {}. Update vertex", label, dataVertex.getUniqueId());
317 return janusGraphDao.updateVertex(dataVertex);
320 log.trace("More than one edge {} to vertex {}. Need to clone vertex", label, dataVertex.getUniqueId());
321 return cloneDataVertex(dataVertex, toscaElementVertex, label, edgeToRemove);
325 private Either<GraphVertex, JanusGraphOperationStatus> cloneDataVertex(GraphVertex dataVertex, GraphVertex toscaElementVertex,
326 EdgeLabelEnum label, Edge edgeToRemove) {
327 GraphVertex newDataVertex = new GraphVertex(dataVertex.getLabel());
328 String id = IdBuilderUtils.generateChildId(toscaElementVertex.getUniqueId(), dataVertex.getLabel());
329 newDataVertex.cloneData(dataVertex);
330 newDataVertex.setUniqueId(id);
331 Either<GraphVertex, JanusGraphOperationStatus> createVertex = janusGraphDao.createVertex(newDataVertex);
332 if (createVertex.isRight()) {
333 log.debug("Failed to clone data vertex for {} error {}", dataVertex.getUniqueId(), createVertex.right().value());
336 newDataVertex = createVertex.left().value();
337 JanusGraphOperationStatus createEdge = janusGraphDao
338 .createEdge(toscaElementVertex, newDataVertex, label, janusGraphDao.getEdgeProperties(edgeToRemove));
339 if (createEdge != JanusGraphOperationStatus.OK) {
340 log.debug("Failed to associate vertex {} to vertex {}, error {}", toscaElementVertex.getUniqueId(), newDataVertex.getUniqueId(),
342 return Either.right(createEdge);
344 edgeToRemove.remove();
345 return Either.left(newDataVertex);
348 public Either<GraphVertex, StorageOperationStatus> associateElementToData(GraphVertex element, VertexTypeEnum vertexLabel,
349 EdgeLabelEnum edgeLabel,
350 Map<String, ? extends ToscaDataDefinition> data) {
351 GraphVertex dataV = new GraphVertex(vertexLabel);
352 String id = IdBuilderUtils.generateChildId(element.getUniqueId(), vertexLabel);
353 dataV.setUniqueId(id);
355 Either<GraphVertex, JanusGraphOperationStatus> createVertex = janusGraphDao.createVertex(dataV);
356 if (createVertex.isRight()) {
357 log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
358 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createVertex.right().value()));
360 dataV = createVertex.left().value();
361 JanusGraphOperationStatus createEdgeStatus = janusGraphDao.createEdge(element.getVertex(), dataV.getVertex(), edgeLabel, new HashMap<>());
362 if (createEdgeStatus != JanusGraphOperationStatus.OK) {
363 log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
364 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeStatus));
366 return Either.left(dataV);
370 * Adds tosca data element to tosca element according received labels
372 * @param toscaElement
379 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
380 VertexTypeEnum vertexLabel, T toscaData,
381 JsonPresentationFields mapKeyField) {
382 List<T> toscaDataList = new ArrayList<>();
383 toscaDataList.add(toscaData);
384 return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
388 * Adds list of tosca data deep elements to tosca element according received labels
390 * @param toscaElement
393 * @param toscaDataList
398 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement,
399 EdgeLabelEnum edgeLabel,
400 VertexTypeEnum vertexLabel,
401 List<T> toscaDataList, List<String> pathKeys,
402 JsonPresentationFields mapKeyField) {
403 return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, false);
407 * Updates list of tosca data elements of tosca element according received labels
409 * @param toscaElement
416 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
417 VertexTypeEnum vertexLabel, T toscaData,
418 JsonPresentationFields mapKeyField) {
419 List<T> toscaDataList = new ArrayList<>();
420 toscaDataList.add(toscaData);
421 return updateToscaDataOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
425 * Updates tosca data deep element of tosca element according received labels
427 * @param toscaElement
435 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(GraphVertex toscaElement,
436 EdgeLabelEnum edgeLabel,
437 VertexTypeEnum vertexLabel, T toscaData,
438 List<String> pathKeys,
439 JsonPresentationFields mapKeyField) {
440 List<T> toscaDataList = new ArrayList<>();
441 toscaDataList.add(toscaData);
442 return updateToscaDataDeepElementsOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
446 * Updates tosca data deep elements of tosca element according received labels
448 * @param toscaElement
451 * @param toscaDataList
456 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(GraphVertex toscaElement,
457 EdgeLabelEnum edgeLabel,
458 VertexTypeEnum vertexLabel,
459 List<T> toscaDataList,
460 List<String> pathKeys,
461 JsonPresentationFields mapKeyField) {
462 return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, true);
466 * Adds tosca data element to tosca element with specified uid according received labels
468 * @param toscaElementUid
475 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
476 VertexTypeEnum vertexLabel, T toscaData,
477 JsonPresentationFields mapKeyField) {
478 List<T> toscaDataList = new ArrayList<>();
479 toscaDataList.add(toscaData);
480 return addToscaDataToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
484 * Adds tosca data deep element to tosca element with specified uid according received labels
486 * @param toscaElementUid
494 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(String toscaElementUid,
495 EdgeLabelEnum edgeLabel,
496 VertexTypeEnum vertexLabel, T toscaData,
497 List<String> pathKeys,
498 JsonPresentationFields mapKeyField) {
499 List<T> toscaDataList = new ArrayList<>();
500 toscaDataList.add(toscaData);
501 return addToscaDataDeepElementsToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
504 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(String toscaElementUid,
505 EdgeLabelEnum edgeLabel,
506 VertexTypeEnum vertexLabel, T toscaData,
507 List<String> pathKeys,
508 JsonPresentationFields mapKeyField) {
509 List<T> toscaDataList = new ArrayList<>();
510 toscaDataList.add(toscaData);
511 return updateToscaDataDeepElementsOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
514 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(String toscaElementUid,
515 EdgeLabelEnum edgeLabel,
516 VertexTypeEnum vertexLabel,
517 List<T> toscaDataList,
518 List<String> pathKeys,
519 JsonPresentationFields mapKeyField) {
520 StorageOperationStatus statusRes = null;
521 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
522 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
523 if (getToscaElementRes.isRight()) {
524 JanusGraphOperationStatus status = getToscaElementRes.right().value();
526 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
527 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
529 if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
530 statusRes = updateToscaDataDeepElementsOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys,
533 if (statusRes == null) {
534 statusRes = StorageOperationStatus.OK;
539 StorageOperationStatus overrideToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
540 Map<String, ? extends ToscaDataDefinition> toscaData) {
541 return janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse).left()
542 .bind(graphVertex -> overrideToscaElementData(graphVertex, toscaData, edgeLabel))
543 .either(graphVertex -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
546 private Either<GraphVertex, JanusGraphOperationStatus> overrideToscaElementData(GraphVertex toscaElement,
547 Map<String, ? extends ToscaDataDefinition> toscaData,
548 EdgeLabelEnum edgeLabelEnum) {
549 return janusGraphDao.getChildVertex(toscaElement, edgeLabelEnum, JsonParseFlagEnum.ParseJson).left()
550 .bind(dataVertex -> overrideToscaElementData(dataVertex, toscaElement, toscaData, edgeLabelEnum)).right().map(
551 err -> logAndReturn(err, "failed to override tosca data for element {} of type {}. status: {}", toscaElement.getUniqueId(),
552 edgeLabelEnum, err));
555 private Either<GraphVertex, JanusGraphOperationStatus> overrideToscaElementData(GraphVertex dataElement, GraphVertex toscaElement,
556 Map<String, ? extends ToscaDataDefinition> toscaData,
557 EdgeLabelEnum edgeLabelEnum) {
558 dataElement.setJson(toscaData);
559 return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabelEnum);
563 * Adds list of tosca data deep elements to tosca element with specified uid according received labels
565 * @param toscaElementUid
568 * @param toscaDataList
573 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(String toscaElementUid,
574 EdgeLabelEnum edgeLabel,
575 VertexTypeEnum vertexLabel,
576 List<T> toscaDataList, List<String> pathKeys,
577 JsonPresentationFields mapKeyField) {
578 StorageOperationStatus statusRes = null;
579 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
580 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
581 if (getToscaElementRes.isRight()) {
582 JanusGraphOperationStatus status = getToscaElementRes.right().value();
584 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
585 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
587 if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
588 statusRes = addToscaDataDeepElementsToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys,
591 if (statusRes == null) {
592 statusRes = StorageOperationStatus.OK;
597 public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockOfToscaElement(String toscaElementUid,
598 EdgeLabelEnum edgeLabel,
600 StorageOperationStatus statusRes = null;
601 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
602 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
603 if (getToscaElementRes.isRight()) {
604 JanusGraphOperationStatus status = getToscaElementRes.right().value();
606 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
607 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
609 if (statusRes == null) {
610 statusRes = deleteToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, key);
612 if (statusRes == null) {
613 statusRes = StorageOperationStatus.OK;
618 public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
619 EdgeLabelEnum edgeLabel,
621 StorageOperationStatus result = null;
622 GraphVertex toscaDataVertex = null;
623 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
624 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
625 if (toscaDataVertexRes.isRight()) {
626 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
627 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
628 toscaElement.getUniqueId(), edgeLabel, status);
629 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
631 if (result == null) {
632 toscaDataVertex = toscaDataVertexRes.left().value();
633 result = deleteDeepElementsBlock(toscaDataVertex, key);
635 if (result == null) {
636 Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
637 if (updateOrCopyRes.isRight()) {
638 JanusGraphOperationStatus status = updateOrCopyRes.right().value();
640 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca data block {} from the tosca element {}. Status is {}. ",
641 edgeLabel, toscaElement.getUniqueId(), status);
642 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
645 if (result == null) {
646 result = StorageOperationStatus.OK;
651 @SuppressWarnings("rawtypes")
652 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(String toscaElementUid,
653 EdgeLabelEnum edgeLabel,
654 VertexTypeEnum vertexLabel,
655 MapDataDefinition toscaDataMap,
657 StorageOperationStatus statusRes = null;
658 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
659 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
660 if (getToscaElementRes.isRight()) {
661 JanusGraphOperationStatus status = getToscaElementRes.right().value();
663 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
664 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
666 if (statusRes == null && toscaDataMap != null) {
667 statusRes = addToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataMap, key);
669 if (statusRes == null) {
670 statusRes = StorageOperationStatus.OK;
675 @SuppressWarnings("rawtypes")
676 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
677 EdgeLabelEnum edgeLabel,
678 VertexTypeEnum vertexLabel,
679 MapDataDefinition toscaDataMap,
681 StorageOperationStatus result = null;
682 GraphVertex toscaDataVertex = null;
683 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
684 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
685 if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
686 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
687 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
688 toscaElement.getUniqueId(), edgeLabel, status);
689 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
691 if (result == null && toscaDataVertexRes.isLeft()) {
692 toscaDataVertex = toscaDataVertexRes.left().value();
693 result = addDeepElementsBlock(toscaDataVertex, toscaDataMap, key);
695 if (result == null) {
696 if (toscaDataVertex != null) {
697 Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
698 if (updateOrCopyRes.isRight()) {
699 JanusGraphOperationStatus status = updateOrCopyRes.right().value();
701 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel,
702 toscaElement.getUniqueId(), status);
703 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
706 Map<String, MapDataDefinition> data = new HashMap<>();
707 data.put(key, toscaDataMap);
708 Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, data);
709 if (createRes.isRight()) {
710 StorageOperationStatus status = createRes.right().value();
711 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ",
712 edgeLabel, toscaElement.getUniqueId(), status);
717 if (result == null) {
718 result = StorageOperationStatus.OK;
724 * @param toscaElementId the id of the tosca element data container
725 * @param edgeLabel the edge label of the data type to update
726 * @param toscaDataMap the data to update
727 * @param key the key in the json object where the map object block resides
728 * @return the status of the update operation
730 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(String toscaElementId,
731 EdgeLabelEnum edgeLabel,
732 MapDataDefinition<T> toscaDataMap,
734 return janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse)
735 .either(toscaElement -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, edgeLabel, toscaDataMap, key),
736 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
739 private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
740 EdgeLabelEnum edgeLabel,
741 MapDataDefinition<T> toscaDataMap,
743 return janusGraphDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson).left()
744 .bind(dataVertex -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, dataVertex, edgeLabel, toscaDataMap, key))
745 .either(updatedVertex -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
748 private <T extends ToscaDataDefinition> Either<GraphVertex, JanusGraphOperationStatus> updateToscaDataDeepElementsBlockToToscaElement(
749 GraphVertex toscaElement, GraphVertex dataElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
750 Map<String, T> mapToscaDataDefinition = toscaDataMap.getMapToscaDataDefinition();
751 updateDeepElements(dataElement, mapToscaDataDefinition, Collections.singletonList(key));
752 return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabel).right().map(
753 err -> logAndReturn(err, "failed while trying to update data vertex from tosca element {}, of type {} . status {}",
754 toscaElement.getUniqueId(), edgeLabel, err));
758 * Updates tosca data element of tosca element by specified uid according received labels
760 * @param toscaElementUid
767 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
768 VertexTypeEnum vertexLabel, T toscaData,
769 JsonPresentationFields mapKeyField) {
770 List<T> toscaDataList = new ArrayList<>();
771 toscaDataList.add(toscaData);
772 return updateToscaDataOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
776 * Updates list of tosca data elements belonging to tosca element with specified uid according received labels
778 * @param toscaElementUid
781 * @param toscaDataList
785 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
786 VertexTypeEnum vertexLabel, List<T> toscaDataList,
787 JsonPresentationFields mapKeyField) {
788 StorageOperationStatus statusRes = null;
789 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
790 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
791 if (getToscaElementRes.isRight()) {
792 JanusGraphOperationStatus status = getToscaElementRes.right().value();
794 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
795 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
797 if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
798 statusRes = updateToscaDataOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
800 if (statusRes == null) {
801 statusRes = StorageOperationStatus.OK;
807 * Adds list of tosca data elements to tosca element with specified uid according received labels
809 * @param toscaElementUid
812 * @param toscaDataList
816 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
817 VertexTypeEnum vertexLabel, List<T> toscaDataList,
818 JsonPresentationFields mapKeyField) {
819 StorageOperationStatus statusRes = null;
820 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
821 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
822 if (getToscaElementRes.isRight()) {
823 JanusGraphOperationStatus status = getToscaElementRes.right().value();
825 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
826 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
828 if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
829 statusRes = addToscaDataToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
831 if (statusRes == null) {
832 statusRes = StorageOperationStatus.OK;
838 * Converts recieved map of tosca data elements to list and adds it to tosca element according received labels
840 * @param toscaElement
843 * @param toscaDataMap
847 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
848 VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap,
849 JsonPresentationFields mapKeyField) {
850 return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()),
855 * Adds list of tosca data elements to tosca element according received labels
857 * @param toscaElement
860 * @param toscaDataList
864 public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
865 VertexTypeEnum vertexLabel, List<T> toscaDataList,
866 JsonPresentationFields mapKeyField) {
867 return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, false);
871 * Updates list of tosca data elements belonging to tosca element according received labels
873 * @param toscaElement
876 * @param toscaDataList
880 public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
881 VertexTypeEnum vertexLabel, List<T> toscaDataList,
882 JsonPresentationFields mapKeyField) {
883 return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, true);
886 public boolean hasEdgeOfType(GraphVertex toscaElement, EdgeLabelEnum edgeLabel) {
887 Either<GraphVertex, JanusGraphOperationStatus> vertex = janusGraphDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
888 return vertex.isLeft();
891 @SuppressWarnings("unchecked")
892 private <T extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
893 VertexTypeEnum vertexLabel, List<T> toscaDataList,
894 JsonPresentationFields mapKeyField, boolean isUpdate) {
895 StorageOperationStatus result = null;
896 GraphVertex toscaDataVertex = null;
897 Map<String, T> existingToscaDataMap = null;
898 Either<Map<String, T>, StorageOperationStatus> validateRes = null;
899 Map<String, T> mergedToscaDataMap;
900 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
901 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
902 if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
903 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
904 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
905 toscaElement.getUniqueId(), edgeLabel, status);
906 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
908 if (result == null) {
909 if (toscaDataVertexRes.isLeft()) {
910 toscaDataVertex = toscaDataVertexRes.left().value();
911 existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
913 validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingToscaDataMap, isUpdate);
914 if (validateRes.isRight()) {
915 result = validateRes.right().value();
916 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ",
917 toscaElement.getUniqueId(), edgeLabel, result);
920 if (result == null) {
921 mergedToscaDataMap = validateRes.left().value();
922 result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, mergedToscaDataMap);
924 if (result == null) {
925 result = StorageOperationStatus.OK;
930 <T extends ToscaDataDefinition> StorageOperationStatus updateFullToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
931 VertexTypeEnum vertexLabel, Map<String, T> toscaData) {
932 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
933 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
934 if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
935 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
936 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
937 toscaElement.getUniqueId(), edgeLabel, status);
938 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
940 GraphVertex toscaDataVertex = null;
941 if (toscaDataVertexRes.isLeft()) {
942 toscaDataVertex = toscaDataVertexRes.left().value();
944 StorageOperationStatus result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaData);
945 return result == null ? StorageOperationStatus.OK : result;
948 @SuppressWarnings({"rawtypes", "unchecked"})
949 private <T, K extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaDataDeepElement(GraphVertex toscaElement,
950 EdgeLabelEnum edgeLabel,
951 VertexTypeEnum vertexLabel,
952 List<K> toscaDataList, List<String> pathKeys,
953 JsonPresentationFields mapKeyField,
955 StorageOperationStatus result = null;
956 GraphVertex toscaDataVertex = null;
957 Map<String, K> existingDeepElementsMap = null;
958 Either<Map<String, K>, StorageOperationStatus> validateRes = null;
959 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
960 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
961 if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
962 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
963 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
964 toscaElement.getUniqueId(), edgeLabel, status);
965 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
967 if (result == null) {
968 if (toscaDataVertexRes.isLeft()) {
969 toscaDataVertex = toscaDataVertexRes.left().value();
970 existingDeepElementsMap = getDeepElements(toscaDataVertex, pathKeys);
972 validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingDeepElementsMap, isUpdate);
973 if (validateRes.isRight()) {
974 result = validateRes.right().value();
975 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ",
976 toscaElement.getUniqueId(), edgeLabel, result);
979 if (result == null) {
980 updateDeepElements(toscaDataVertex, validateRes.left().value(), pathKeys);
981 Map<String, K> toscaDataToHandle;
982 if (toscaDataVertex == null) {
983 toscaDataToHandle = new HashMap<>();
984 Map<String, K> currMap = toscaDataToHandle;
985 for (int i = 1; i < pathKeys.size() - 1; ++i) {
986 currMap.put(pathKeys.get(i), (K) new MapDataDefinition());
987 currMap = (Map<String, K>) ((MapDataDefinition) currMap).getMapToscaDataDefinition().get(pathKeys.get(i));
989 toscaDataToHandle.put(pathKeys.get(pathKeys.size() - 1), (K) new MapDataDefinition(validateRes.left().value()));
991 toscaDataToHandle = (Map<String, K>) toscaDataVertex.getJson();
993 result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaDataToHandle);
995 if (result == null) {
996 result = StorageOperationStatus.OK;
1001 @SuppressWarnings({"rawtypes", "unchecked"})
1002 private <T, K extends ToscaDataDefinition> void updateDeepElements(GraphVertex toscaDataVertex, Map<String, K> mergedDeepElementMap,
1003 List<String> pathKeys) {
1004 if (toscaDataVertex != null && MapUtils.isNotEmpty(mergedDeepElementMap)) {
1005 Map<String, MapDataDefinition> currMap = (Map<String, MapDataDefinition>) toscaDataVertex.getJson();
1006 if (!currMap.containsKey(pathKeys.get(0))) {
1007 currMap.put(pathKeys.get(0), new MapDataDefinition<>());
1009 Object object = currMap.get(pathKeys.get(0));
1010 MapDataDefinition currDeepElement = null;
1011 if (object instanceof MapDataDefinition) {
1012 currDeepElement = (MapDataDefinition) object;
1014 currDeepElement = new MapDataDefinition(currMap);
1016 for (int i = 1; i < pathKeys.size(); ++i) {
1017 if (currDeepElement.findByKey(pathKeys.get(i)) == null) {
1018 currDeepElement.put(pathKeys.get(i), new MapDataDefinition<>());
1020 currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
1022 if (currDeepElement != null) {
1023 for (Map.Entry<String, K> elementEntry : mergedDeepElementMap.entrySet()) {
1024 currDeepElement.put(elementEntry.getKey(), elementEntry.getValue());
1030 @SuppressWarnings({"unchecked", "rawtypes"})
1031 private <T, K extends ToscaDataDefinition> Map<String, K> getDeepElements(GraphVertex toscaDataVertex, List<String> pathKeys) {
1032 Map<String, K> result = null;
1033 Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1034 MapDataDefinition currDeepElement = (MapDataDefinition) currMap.get(pathKeys.get(0));
1035 for (int i = 1; i < pathKeys.size(); ++i) {
1036 currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
1038 if (currDeepElement != null) {
1039 result = (Map<String, K>) currDeepElement.getMapToscaDataDefinition();
1044 @SuppressWarnings("unchecked")
1045 private <T extends ToscaDataDefinition> StorageOperationStatus addDeepElementsBlock(GraphVertex toscaDataVertex, T toscaDataBlock, String key) {
1046 StorageOperationStatus result = null;
1047 Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1048 if (currMap.containsKey(key)) {
1049 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1050 "Failed to add block of deep tosca data elements by label {}." + " The block element with the same key {} already exists. ",
1051 toscaDataVertex.getLabel(), key);
1052 result = StorageOperationStatus.ENTITY_ALREADY_EXISTS;
1054 if (result == null) {
1055 currMap.put(key, toscaDataBlock);
1060 @SuppressWarnings("unchecked")
1061 private <T extends ToscaDataDefinition> StorageOperationStatus deleteDeepElementsBlock(GraphVertex toscaDataVertex, String key) {
1062 StorageOperationStatus result = null;
1063 Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1064 if (!currMap.containsKey(key)) {
1065 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1066 "Failed to delete block of deep tosca data elements by label {}." + " The block element with the same key {} doesn't exist. ",
1067 toscaDataVertex.getLabel(), key);
1068 result = StorageOperationStatus.NOT_FOUND;
1070 if (result == null) {
1071 currMap.remove(key);
1077 * Removes tosca data vertex belonging to tosca element specified by uid according label
1079 * @param toscaElementUid
1083 public StorageOperationStatus removeToscaData(String toscaElementUid, EdgeLabelEnum edgeLabel) {
1084 StorageOperationStatus statusRes = StorageOperationStatus.OK;
1085 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1086 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1087 if (getToscaElementRes.isRight()) {
1088 JanusGraphOperationStatus status = getToscaElementRes.right().value();
1090 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1091 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1093 if (statusRes == StorageOperationStatus.OK) {
1094 statusRes = removeToscaDataVertex(getToscaElementRes.left().value(), edgeLabel);
1100 * Removes tosca data vertex belonging to tosca element according label
1102 * @param toscaElement
1106 private StorageOperationStatus removeToscaDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel) {
1107 StorageOperationStatus result = null;
1108 GraphVertex toscaDataVertex = null;
1109 Iterator<Edge> edges = null;
1110 int edgeCounter = 0;
1112 Edge edgeToDelete = null;
1113 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1114 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1115 if (toscaDataVertexRes.isRight()) {
1116 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1117 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1118 toscaElement.getUniqueId(), edgeLabel, status);
1119 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1121 if (result == null) {
1122 toscaDataVertex = toscaDataVertexRes.left().value();
1123 edges = toscaDataVertex.getVertex().edges(Direction.IN);
1124 if (edges == null || !edges.hasNext()) {
1125 result = StorageOperationStatus.NOT_FOUND;
1126 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1127 toscaElement.getUniqueId(), edgeLabel, result);
1130 if (result == null) {
1131 if (edges != null) {
1132 while (edges.hasNext()) {
1134 edge = edges.next();
1135 if (edge.outVertex().id().equals(toscaElement.getVertex().id())) {
1136 edgeToDelete = edge;
1141 if (edgeToDelete == null) {
1142 result = StorageOperationStatus.NOT_FOUND;
1143 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1144 toscaElement.getUniqueId(), edgeLabel, result);
1147 if (result == null) {
1148 if (edgeCounter > 1 && edgeToDelete != null) {
1149 edgeToDelete.remove();
1151 toscaDataVertex.getVertex().remove();
1154 if (result == null) {
1155 result = StorageOperationStatus.OK;
1161 * Deletes tosca data elements belonging to tosca element specified by uid according label
1163 * @param toscaElementUid
1168 public StorageOperationStatus deleteToscaDataElements(String toscaElementUid, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
1169 StorageOperationStatus statusRes = StorageOperationStatus.OK;
1170 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1171 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1172 if (getToscaElementRes.isRight()) {
1173 JanusGraphOperationStatus status = getToscaElementRes.right().value();
1175 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1176 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1178 if (statusRes == StorageOperationStatus.OK) {
1179 statusRes = deleteToscaDataElements(getToscaElementRes.left().value(), edgeLabel, uniqueKeys);
1185 * Deletes tosca data element belonging to tosca element specified by uid according label
1187 * @param toscaElementUid
1189 * @param vertexLabel
1191 * @param mapKeyField
1194 public StorageOperationStatus deleteToscaDataElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1195 String uniqueKey, JsonPresentationFields mapKeyField) {
1196 StorageOperationStatus statusRes = StorageOperationStatus.OK;
1197 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1198 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1199 if (getToscaElementRes.isRight()) {
1200 JanusGraphOperationStatus status = getToscaElementRes.right().value();
1202 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1203 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1205 if (statusRes == StorageOperationStatus.OK) {
1206 statusRes = deleteToscaDataElement(getToscaElementRes.left().value(), edgeLabel, uniqueKey);
1212 * Deletes tosca data deep element belonging to tosca element specified by uid according label
1214 * @param toscaElementUid
1220 public StorageOperationStatus deleteToscaDataDeepElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
1221 String uniqueKey, List<String> pathKeys) {
1222 StorageOperationStatus statusRes = StorageOperationStatus.OK;
1223 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1224 getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1225 if (getToscaElementRes.isRight()) {
1226 JanusGraphOperationStatus status = getToscaElementRes.right().value();
1228 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1229 statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1231 if (statusRes == StorageOperationStatus.OK) {
1232 statusRes = deleteToscaDataDeepElement(getToscaElementRes.left().value(), edgeLabel, uniqueKey, pathKeys);
1238 * Deletes tosca data deep element belonging to tosca element according label
1240 * @param toscaElement
1246 public StorageOperationStatus deleteToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
1247 String uniqueKey, List<String> pathKeys) {
1248 List<String> uniqueKeys = new ArrayList<>();
1249 uniqueKeys.add(uniqueKey);
1250 return deleteToscaDataDeepElements(toscaElement, edgeLabel, uniqueKeys, pathKeys);
1253 public StorageOperationStatus deleteToscaDataDeepElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
1254 List<String> uniqueKeys, List<String> pathKeys) {
1255 StorageOperationStatus result = null;
1256 GraphVertex toscaDataVertex;
1257 Map<String, ToscaDataDefinition> existingToscaDataMap = null;
1258 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1259 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1260 if (toscaDataVertexRes.isRight()) {
1261 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1262 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1263 toscaElement.getUniqueId(), edgeLabel, status);
1264 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1266 if (result == null) {
1267 toscaDataVertex = toscaDataVertexRes.left().value();
1268 existingToscaDataMap = getDeepElements(toscaDataVertexRes.left().value(), pathKeys);
1269 result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
1271 if (result == null) {
1272 result = StorageOperationStatus.OK;
1277 private StorageOperationStatus deleteElementsFromDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys,
1278 GraphVertex toscaDataVertex, Map<String, ToscaDataDefinition> existingToscaDataMap) {
1279 StorageOperationStatus result;
1280 for (String uniqueKey : uniqueKeys) {
1281 result = removeKeyFromDataVertex(uniqueKey, existingToscaDataMap);
1282 if (result != StorageOperationStatus.OK) {
1283 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1284 "Failed to delete tosca data element of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel,
1289 result = updateToscaDataElement(toscaElement, edgeLabel, toscaDataVertex);
1294 * Deletes tosca data element belonging to tosca element according label
1296 * @param toscaElement
1301 public StorageOperationStatus deleteToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
1303 List<String> uniqueKeys = new ArrayList<>();
1304 uniqueKeys.add(uniqueKey);
1305 return deleteToscaDataElements(toscaElement, edgeLabel, uniqueKeys);
1308 @SuppressWarnings("unchecked")
1310 * Deletes tosca data elements belonging to tosca element according label
1311 * @param toscaElement
1316 public StorageOperationStatus deleteToscaDataElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
1317 StorageOperationStatus result = null;
1318 GraphVertex toscaDataVertex;
1319 Map<String, ToscaDataDefinition> existingToscaDataMap;
1320 Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1321 .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1322 if (toscaDataVertexRes.isRight()) {
1323 JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1324 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1325 toscaElement.getUniqueId(), edgeLabel, status);
1326 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1328 if (result == null) {
1329 toscaDataVertex = toscaDataVertexRes.left().value();
1330 existingToscaDataMap = (Map<String, ToscaDataDefinition>) toscaDataVertex.getJson();
1331 result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
1333 if (result == null) {
1334 result = StorageOperationStatus.OK;
1340 * Adds the map data entry to the graph vertex of the specified type, related with the specified edge to the component specified by ID
1342 * @param componentId The uniqueId of the component
1343 * @param vertexTypeEnum The type of the vertex
1344 * @param edgeLabelEnum The type of the edge
1345 * @param mapDataEntry The map data entry
1346 * @param <T extends MapDataDefinition>
1347 * @return The status of the operation result
1349 public <T extends MapDataDefinition> StorageOperationStatus addElementToComponent(String componentId, VertexTypeEnum vertexTypeEnum,
1350 EdgeLabelEnum edgeLabelEnum,
1351 Map.Entry<String, T> mapDataEntry) {
1352 if (MapUtils.isNotEmpty(mapDataEntry.getValue().getMapToscaDataDefinition())) {
1353 return addToscaDataDeepElementsBlockToToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, mapDataEntry.getValue(),
1354 mapDataEntry.getKey());
1356 return StorageOperationStatus.OK;
1359 private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
1360 GraphVertex toscaDataVertex) {
1361 StorageOperationStatus result = StorageOperationStatus.OK;
1362 Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
1363 if (updateOrCopyRes.isRight()) {
1364 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateOrCopyRes.right().value());
1365 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca data {} of the tosca element {}. Status is {}. ", edgeLabel,
1366 toscaElement.getUniqueId(), result);
1371 private <T extends ToscaDataDefinition> StorageOperationStatus removeKeyFromDataVertex(String uniqueKey, Map<String, T> existingToscaDataMap) {
1372 if (!existingToscaDataMap.containsKey(uniqueKey)) {
1373 return StorageOperationStatus.NOT_FOUND;
1375 existingToscaDataMap.remove(uniqueKey);
1376 return StorageOperationStatus.OK;
1379 <K extends ToscaDataDefinition> StorageOperationStatus handleToscaData(GraphVertex toscaElement, VertexTypeEnum vertexLabel,
1380 EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex,
1381 Map<String, K> mergedToscaDataMap) {
1382 StorageOperationStatus result = StorageOperationStatus.OK;
1383 if (toscaDataVertex == null) {
1384 if (MapUtils.isEmpty(mergedToscaDataMap)) {
1385 //If no new data and this vertex type does not exist, return
1388 Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, mergedToscaDataMap);
1389 if (createRes.isRight()) {
1390 StorageOperationStatus status = createRes.right().value();
1392 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel,
1393 toscaElement.getUniqueId(), status);
1397 if (MapUtils.isEmpty(mergedToscaDataMap)) {
1398 JanusGraphOperationStatus janusGraphOperationStatus = janusGraphDao.disassociateAndDeleteLast(toscaElement, Direction.OUT, edgeLabel);
1399 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus);
1401 toscaDataVertex.setJson(mergedToscaDataMap);
1402 Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
1403 if (updateOrCopyRes.isRight()) {
1404 JanusGraphOperationStatus status = updateOrCopyRes.right().value();
1406 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel,
1407 toscaElement.getUniqueId(), status);
1408 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1414 private <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> validateMergeToscaData(GraphVertex toscaElement,
1415 List<T> toscaDataList,
1416 JsonPresentationFields mapKeyField,
1417 Map<String, T> existingToscaDataMap,
1419 Map<String, T> mergedToscaDataMap = new HashMap<>();
1420 StorageOperationStatus status;
1421 Either<Map<String, T>, StorageOperationStatus> result = Either.left(mergedToscaDataMap);
1422 if (MapUtils.isNotEmpty(existingToscaDataMap)) {
1423 mergedToscaDataMap.putAll(existingToscaDataMap);
1425 for (T toscaDataElement : toscaDataList) {
1426 status = handleToscaDataElement(toscaElement.getUniqueId(), mapKeyField, mergedToscaDataMap, toscaDataElement, isUpdate);
1427 if (status != StorageOperationStatus.OK) {
1428 return Either.right(status);
1434 private <T extends ToscaDataDefinition> StorageOperationStatus handleToscaDataElement(String toscaElementId,
1435 JsonPresentationFields mapKeyField,
1436 Map<String, T> mergedToscaDataMap, T toscaDataElement,
1438 StorageOperationStatus status = StorageOperationStatus.OK;
1439 String currKey = (String) toscaDataElement.getToscaPresentationValue(mapKeyField);
1440 if (StringUtils.isEmpty(currKey) && toscaDataElement instanceof ListDataDefinition) {
1441 ToscaDataDefinition toscaDataDefinition = ((ListDataDefinition<? extends ToscaDataDefinition>) toscaDataElement)
1442 .getListToscaDataDefinition().get(0);
1443 if (toscaDataDefinition != null) {
1444 currKey = (String) toscaDataDefinition.getToscaPresentationValue(mapKeyField);
1447 if (StringUtils.isEmpty(currKey)) {
1448 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The key is empty. ");
1449 status = StorageOperationStatus.BAD_REQUEST;
1450 } else if (!isUpdate && mergedToscaDataMap.containsKey(currKey)) {
1451 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1452 "Failed to add tosca data to tosca element {}. The element with the same key {} already exists. ", toscaElementId,
1454 status = StorageOperationStatus.BAD_REQUEST;
1456 mergedToscaDataMap.put(currKey, toscaDataElement);
1460 protected GroupInstanceDataDefinition buildGroupInstanceDataDefinition(GroupDataDefinition group,
1461 ComponentInstanceDataDefinition componentInstance) {
1462 String componentInstanceName = componentInstance.getName();
1463 Long creationDate = System.currentTimeMillis();
1464 GroupInstanceDataDefinition groupInstance = new GroupInstanceDataDefinition();
1465 String groupUid = group.getUniqueId();
1466 groupInstance.setGroupUid(groupUid);
1467 groupInstance.setType(group.getType());
1468 groupInstance.setCustomizationUUID(generateCustomizationUUID());
1469 groupInstance.setCreationTime(creationDate);
1470 groupInstance.setModificationTime(creationDate);
1471 groupInstance.setName(buildGroupInstanceName(componentInstanceName, group.getName()));
1472 groupInstance.setGroupName(group.getName());
1473 groupInstance.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(groupInstance.getName()));
1475 .setUniqueId(UniqueIdBuilder.buildResourceInstanceUniqueId(componentInstance.getUniqueId(), groupUid, groupInstance.getNormalizedName()));
1476 groupInstance.setArtifacts(group.getArtifacts());
1477 groupInstance.setArtifactsUuid(group.getArtifactsUuid());
1478 groupInstance.setProperties(group.getProperties());
1479 convertPropertiesToInstanceProperties(groupInstance.getProperties());
1480 groupInstance.setInvariantUUID(group.getInvariantUUID());
1481 groupInstance.setGroupUUID(group.getGroupUUID());
1482 groupInstance.setVersion(group.getVersion());
1483 return groupInstance;
1486 protected String buildGroupInstanceName(String instanceName, String groupName) {
1487 return ValidationUtils.normalizeComponentInstanceName(instanceName) + ".." + groupName;
1490 protected String generateCustomizationUUID() {
1491 return UUID.randomUUID().toString();
1494 protected void convertPropertiesToInstanceProperties(List<PropertyDataDefinition> properties) {
1495 properties.forEach(PropertyDataDefinition::convertPropertyDataToInstancePropertyData);
1498 private JanusGraphOperationStatus logAndReturn(JanusGraphOperationStatus janusGraphOperationStatus, String logMsg, Object... logParams) {
1499 log.debug(logMsg, logParams);
1500 return janusGraphOperationStatus;
1503 protected GraphVertex throwStorageException(JanusGraphOperationStatus status) {
1504 throw new StorageException(status);
1507 public void setHealingPipelineDao(HealingPipelineDao healingPipelineDao) {
1508 this.healingPipelineDao = healingPipelineDao;