Update Interface definition on VFC
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsonjanusgraph / operations / BaseOperation.java
1 /*-
2  * ============LICENSE_START=======================================================
3  * SDC
4  * ================================================================================
5  * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6  * ================================================================================
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  * ============LICENSE_END=========================================================
19  */
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
21
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;
28 import java.util.Map;
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.ArtifactDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
56 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
57 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
58 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
59 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
60 import org.openecomp.sdc.be.model.User;
61 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
62 import org.openecomp.sdc.be.model.operations.StorageException;
63 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
64 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
65 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
66 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
67 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
68 import org.openecomp.sdc.common.log.wrappers.Logger;
69 import org.openecomp.sdc.common.util.ValidationUtils;
70 import org.springframework.beans.factory.annotation.Autowired;
71
72 /**
73  * public abstract class BaseOperation provides base operation functionality and common fields
74  */
75 public abstract class BaseOperation {
76
77     public static final String VF_MODULE = "org.openecomp.groups.VfModule";
78     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 {}. ";
79     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 {}. ";
80     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 {}. ";
81     private static final Logger log = Logger.getLogger(BaseOperation.class.getName());
82     @Autowired
83     protected JanusGraphDao janusGraphDao;
84     @Autowired
85     protected NodeTypeOperation nodeTypeOperation;
86     @Autowired
87     protected TopologyTemplateOperation topologyTemplateOperation;
88     //    @Autowired
89     protected HealingPipelineDao healingPipelineDao;
90
91     public void setJanusGraphDao(JanusGraphDao janusGraphDao) {
92         this.janusGraphDao = janusGraphDao;
93     }
94
95     /**
96      * Returns reference to appropriate toscaTemplateOperation
97      *
98      * @param componentType
99      * @return
100      */
101     public ToscaElementOperation getToscaElementOperation(ComponentTypeEnum componentType) {
102         ToscaElementOperation operation;
103         switch (componentType) {
104             case SERVICE:
105             case RESOURCE:
106                 operation = topologyTemplateOperation;
107                 break;
108             default:
109                 operation = nodeTypeOperation;
110                 break;
111         }
112         return operation;
113     }
114
115     /**
116      * Returns reference to appropriate toscaTemplateOperation
117      *
118      * @param toscaElementType
119      * @return
120      */
121     public ToscaElementOperation getToscaElementOperation(ToscaElementTypeEnum toscaElementType) {
122         ToscaElementOperation operation;
123         switch (toscaElementType) {
124             case TOPOLOGY_TEMPLATE:
125                 operation = topologyTemplateOperation;
126                 break;
127             case NODE_TYPE:
128                 operation = nodeTypeOperation;
129                 break;
130             default:
131                 operation = null;
132                 break;
133         }
134         return operation;
135     }
136
137     /**
138      * Returns reference to appropriate toscaTemplateOperation
139      *
140      * @param toscaElementType
141      * @return
142      */
143     public ToscaElementOperation getToscaElementOperation(VertexTypeEnum toscaElementType) {
144         ToscaElementOperation operation;
145         switch (toscaElementType) {
146             case TOPOLOGY_TEMPLATE:
147                 operation = topologyTemplateOperation;
148                 break;
149             case NODE_TYPE:
150                 operation = nodeTypeOperation;
151                 break;
152             default:
153                 operation = null;
154                 break;
155         }
156         return operation;
157     }
158
159     /**
160      * Converts received vertex to User object
161      *
162      * @param ownerV
163      * @return
164      */
165     public User convertToUser(Vertex ownerV) {
166         User owner = new User();
167         owner.setUserId((String) ownerV.property(GraphPropertyEnum.USERID.getProperty()).value());
168         VertexProperty<Object> property = ownerV.property(GraphPropertyEnum.ROLE.getProperty());
169         if (property != null && property.isPresent()) {
170             owner.setRole((String) property.value());
171         }
172         property = ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty());
173         if (property != null && property.isPresent()) {
174             owner.setFirstName((String) ownerV.property(GraphPropertyEnum.FIRST_NAME.getProperty()).value());
175         }
176         property = ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty());
177         if (property != null && property.isPresent()) {
178             owner.setLastName((String) ownerV.property(GraphPropertyEnum.LAST_NAME.getProperty()).value());
179         }
180         property = ownerV.property(GraphPropertyEnum.EMAIL.getProperty());
181         if (property != null && property.isPresent()) {
182             owner.setEmail((String) ownerV.property(GraphPropertyEnum.EMAIL.getProperty()).value());
183         }
184         property = ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty());
185         if (property != null && property.isPresent()) {
186             owner.setLastLoginTime((Long) ownerV.property(GraphPropertyEnum.LAST_LOGIN_TIME.getProperty()).value());
187         }
188         return owner;
189     }
190
191     protected <T extends ToscaDataDefinition> Either<Map<String, T>, JanusGraphOperationStatus> getDataFromGraph(GraphVertex componentV,
192                                                                                                                  EdgeLabelEnum edgelabel) {
193         Either<Pair<GraphVertex, Map<String, T>>, JanusGraphOperationStatus> dataVertex = getDataAndVertexFromGraph(componentV, edgelabel);
194         if (dataVertex.isRight()) {
195             return Either.right(dataVertex.right().value());
196         }
197         Map<String, T> properties = dataVertex.left().value().getRight();
198         return Either.left(properties);
199     }
200
201     @SuppressWarnings("unchecked")
202     protected <T extends ToscaDataDefinition> Either<Pair<GraphVertex, Map<String, T>>, JanusGraphOperationStatus> getDataAndVertexFromGraph(
203         GraphVertex componentV, EdgeLabelEnum edgelabel) {
204         Either<GraphVertex, JanusGraphOperationStatus> dataVertex = getDataVertex(componentV, edgelabel);
205         if (dataVertex.isRight()) {
206             return Either.right(dataVertex.right().value());
207         }
208         GraphVertex propV = dataVertex.left().value();
209         Map<String, T> properties = (Map<String, T>) propV.getJson();
210         Pair<GraphVertex, Map<String, T>> pair = new ImmutablePair<>(propV, properties);
211         return Either.left(pair);
212     }
213
214     protected <T extends ToscaDataDefinition> Either<GraphVertex, JanusGraphOperationStatus> getDataVertex(GraphVertex componentV,
215                                                                                                            EdgeLabelEnum edgelabel) {
216         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao.getChildVertex(componentV, edgelabel, JsonParseFlagEnum.ParseJson);
217         if (childVertex.isRight()) {
218             if (childVertex.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
219                 log.debug("failed to fetch {} for tosca element with id {}, error {}", edgelabel, componentV.getUniqueId(),
220                     childVertex.right().value());
221             }
222             return Either.right(childVertex.right().value());
223         }
224         GraphVertex propV = childVertex.left().value();
225         return Either.left(propV);
226     }
227
228     /**
229      * Returns tosca data belonging to tosca element specified by uid according received label
230      *
231      * @param toscaElementUid
232      * @param edgelabel
233      * @return
234      */
235     public <T extends ToscaDataDefinition> Either<Map<String, T>, JanusGraphOperationStatus> getDataFromGraph(String toscaElementUid,
236                                                                                                               EdgeLabelEnum edgelabel) {
237         Either<Map<String, T>, JanusGraphOperationStatus> result = null;
238         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
239         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
240         if (getToscaElementRes.isRight()) {
241             JanusGraphOperationStatus status = getToscaElementRes.right().value();
242             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get tosca element {} upon getting tosca data from graph. Status is {}. ",
243                 toscaElementUid, status);
244             result = Either.right(status);
245         }
246         if (result == null) {
247             result = getDataFromGraph(getToscaElementRes.left().value(), edgelabel);
248         }
249         return result;
250     }
251
252     public Either<GraphVertex, JanusGraphOperationStatus> findUserVertex(String userId) {
253         return janusGraphDao.getVertexByPropertyAndLabel(GraphPropertyEnum.USERID, userId, VertexTypeEnum.USER, JsonParseFlagEnum.NoParse);
254     }
255
256     /**
257      * @param elemementId
258      * @param label
259      * @return
260      */
261     public Either<Boolean, StorageOperationStatus> isCloneNeeded(String elemementId, EdgeLabelEnum label) {
262         Either<GraphVertex, JanusGraphOperationStatus> vertexById = janusGraphDao.getVertexById(elemementId);
263         if (vertexById.isRight()) {
264             log.debug("Failed to fetch element by id {} error {}", elemementId, vertexById.right().value());
265             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(vertexById.right().value()));
266         }
267         GraphVertex toscaElementVertex = vertexById.left().value();
268         Either<GraphVertex, JanusGraphOperationStatus> childVertex = janusGraphDao
269             .getChildVertex(toscaElementVertex, label, JsonParseFlagEnum.NoParse);
270         if (childVertex.isRight()) {
271             if (childVertex.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
272                 log.debug("failed to fetch {} for tosca element with id {}, error {}", label, toscaElementVertex.getUniqueId(),
273                     childVertex.right().value());
274                 return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(childVertex.right().value()));
275             }
276             return Either.left(Boolean.FALSE);
277         }
278         GraphVertex dataVertex = childVertex.left().value();
279         Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
280         int edgeCount = 0;
281         while (edges.hasNext()) {
282             edges.next();
283             ++edgeCount;
284         }
285         if (edgeCount > 1) {
286             return Either.left(Boolean.TRUE);
287         } else {
288             return Either.left(Boolean.FALSE);
289         }
290     }
291
292     protected Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyOnUpdate(GraphVertex dataVertex, GraphVertex toscaElementVertex,
293                                                                                   EdgeLabelEnum label) {
294         Iterator<Edge> edges = dataVertex.getVertex().edges(Direction.IN, label.name());
295         int edgeCount = 0;
296         Edge edgeToRemove = null;
297         while (edges.hasNext()) {
298             Edge edge = edges.next();
299             ++edgeCount;
300             Vertex outVertex = edge.outVertex();
301             String outId = (String) janusGraphDao.getProperty((JanusGraphVertex) outVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
302             if (toscaElementVertex.getUniqueId().equals(outId)) {
303                 edgeToRemove = edge;
304             }
305         }
306         if (edgeToRemove == null) {
307             log.debug("No edges {} from vertex {} to vertex {}", label, toscaElementVertex.getUniqueId(), dataVertex.getUniqueId());
308             return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
309         }
310         switch (edgeCount) {
311             case 0:
312                 // error
313                 log.debug("No edges {} to vertex {}", label, dataVertex.getUniqueId());
314                 return Either.right(JanusGraphOperationStatus.GENERAL_ERROR);
315             case 1:
316                 // update
317                 log.trace("Only one edge {} to vertex {}. Update vertex", label, dataVertex.getUniqueId());
318                 return janusGraphDao.updateVertex(dataVertex);
319             default:
320                 // copy on update
321                 log.trace("More than one edge {} to vertex {}. Need to clone vertex", label, dataVertex.getUniqueId());
322                 return cloneDataVertex(dataVertex, toscaElementVertex, label, edgeToRemove);
323         }
324     }
325
326     private Either<GraphVertex, JanusGraphOperationStatus> cloneDataVertex(GraphVertex dataVertex, GraphVertex toscaElementVertex,
327                                                                            EdgeLabelEnum label, Edge edgeToRemove) {
328         GraphVertex newDataVertex = new GraphVertex(dataVertex.getLabel());
329         String id = IdBuilderUtils.generateChildId(toscaElementVertex.getUniqueId(), dataVertex.getLabel());
330         newDataVertex.cloneData(dataVertex);
331         newDataVertex.setUniqueId(id);
332         Either<GraphVertex, JanusGraphOperationStatus> createVertex = janusGraphDao.createVertex(newDataVertex);
333         if (createVertex.isRight()) {
334             log.debug("Failed to clone data vertex for {} error {}", dataVertex.getUniqueId(), createVertex.right().value());
335             return createVertex;
336         }
337         newDataVertex = createVertex.left().value();
338         JanusGraphOperationStatus createEdge = janusGraphDao
339             .createEdge(toscaElementVertex, newDataVertex, label, janusGraphDao.getEdgeProperties(edgeToRemove));
340         if (createEdge != JanusGraphOperationStatus.OK) {
341             log.debug("Failed to associate vertex {} to vertex {}, error {}", toscaElementVertex.getUniqueId(), newDataVertex.getUniqueId(),
342                 createEdge);
343             return Either.right(createEdge);
344         }
345         edgeToRemove.remove();
346         return Either.left(newDataVertex);
347     }
348
349     public Either<GraphVertex, StorageOperationStatus> associateElementToData(GraphVertex element, VertexTypeEnum vertexLabel,
350                                                                               EdgeLabelEnum edgeLabel,
351                                                                               Map<String, ? extends ToscaDataDefinition> data) {
352         GraphVertex dataV = new GraphVertex(vertexLabel);
353         String id = IdBuilderUtils.generateChildId(element.getUniqueId(), vertexLabel);
354         dataV.setUniqueId(id);
355         dataV.setJson(data);
356         Either<GraphVertex, JanusGraphOperationStatus> createVertex = janusGraphDao.createVertex(dataV);
357         if (createVertex.isRight()) {
358             log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
359             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createVertex.right().value()));
360         }
361         dataV = createVertex.left().value();
362         JanusGraphOperationStatus createEdgeStatus = janusGraphDao.createEdge(element.getVertex(), dataV.getVertex(), edgeLabel, new HashMap<>());
363         if (createEdgeStatus != JanusGraphOperationStatus.OK) {
364             log.trace("Failed to create {} vertex for type node {}", vertexLabel, element.getUniqueId());
365             return Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeStatus));
366         }
367         return Either.left(dataV);
368     }
369
370     /**
371      * Adds tosca data element to tosca element according received labels
372      *
373      * @param toscaElement
374      * @param edgeLabel
375      * @param vertexLabel
376      * @param toscaData
377      * @param mapKeyField
378      * @return
379      */
380     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
381                                                                                              VertexTypeEnum vertexLabel, T toscaData,
382                                                                                              JsonPresentationFields mapKeyField) {
383         List<T> toscaDataList = new ArrayList<>();
384         toscaDataList.add(toscaData);
385         return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
386     }
387
388     /**
389      * Adds list of tosca data deep elements to tosca element according received labels
390      *
391      * @param toscaElement
392      * @param edgeLabel
393      * @param vertexLabel
394      * @param toscaDataList
395      * @param pathKeys
396      * @param mapKeyField
397      * @return
398      */
399     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(GraphVertex toscaElement,
400                                                                                                          EdgeLabelEnum edgeLabel,
401                                                                                                          VertexTypeEnum vertexLabel,
402                                                                                                          List<T> toscaDataList, List<String> pathKeys,
403                                                                                                          JsonPresentationFields mapKeyField) {
404         return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, false);
405     }
406
407     /**
408      * Updates list of tosca data elements of tosca element according received labels
409      *
410      * @param toscaElement
411      * @param edgeLabel
412      * @param vertexLabel
413      * @param toscaData
414      * @param mapKeyField
415      * @return
416      */
417     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
418                                                                                                 VertexTypeEnum vertexLabel, T toscaData,
419                                                                                                 JsonPresentationFields mapKeyField) {
420         List<T> toscaDataList = new ArrayList<>();
421         toscaDataList.add(toscaData);
422         return updateToscaDataOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
423     }
424
425     /**
426      * Updates tosca data deep element of tosca element according received labels
427      *
428      * @param toscaElement
429      * @param edgeLabel
430      * @param vertexLabel
431      * @param toscaData
432      * @param pathKeys
433      * @param mapKeyField
434      * @return
435      */
436     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(GraphVertex toscaElement,
437                                                                                                            EdgeLabelEnum edgeLabel,
438                                                                                                            VertexTypeEnum vertexLabel, T toscaData,
439                                                                                                            List<String> pathKeys,
440                                                                                                            JsonPresentationFields mapKeyField) {
441         List<T> toscaDataList = new ArrayList<>();
442         toscaDataList.add(toscaData);
443         return updateToscaDataDeepElementsOfToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
444     }
445
446     /**
447      * Updates tosca data deep elements of tosca element according received labels
448      *
449      * @param toscaElement
450      * @param edgeLabel
451      * @param vertexLabel
452      * @param toscaDataList
453      * @param pathKeys
454      * @param mapKeyField
455      * @return
456      */
457     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(GraphVertex toscaElement,
458                                                                                                             EdgeLabelEnum edgeLabel,
459                                                                                                             VertexTypeEnum vertexLabel,
460                                                                                                             List<T> toscaDataList,
461                                                                                                             List<String> pathKeys,
462                                                                                                             JsonPresentationFields mapKeyField) {
463         return updateOrAddToscaDataDeepElement(toscaElement, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField, true);
464     }
465
466     /**
467      * Adds tosca data element to tosca element with specified uid according received labels
468      *
469      * @param toscaElementUid
470      * @param toscaData
471      * @param edgeLabel
472      * @param vertexLabel
473      * @param mapKeyField
474      * @return
475      */
476     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
477                                                                                              VertexTypeEnum vertexLabel, T toscaData,
478                                                                                              JsonPresentationFields mapKeyField) {
479         List<T> toscaDataList = new ArrayList<>();
480         toscaDataList.add(toscaData);
481         return addToscaDataToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
482     }
483
484     /**
485      * Adds tosca data deep element to tosca element with specified uid according received labels
486      *
487      * @param toscaElementUid
488      * @param edgeLabel
489      * @param vertexLabel
490      * @param toscaData
491      * @param pathKeys
492      * @param mapKeyField
493      * @return
494      */
495     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementToToscaElement(String toscaElementUid,
496                                                                                                         EdgeLabelEnum edgeLabel,
497                                                                                                         VertexTypeEnum vertexLabel, T toscaData,
498                                                                                                         List<String> pathKeys,
499                                                                                                         JsonPresentationFields mapKeyField) {
500         List<T> toscaDataList = new ArrayList<>();
501         toscaDataList.add(toscaData);
502         return addToscaDataDeepElementsToToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
503     }
504
505     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementOfToscaElement(String toscaElementUid,
506                                                                                                            EdgeLabelEnum edgeLabel,
507                                                                                                            VertexTypeEnum vertexLabel, T toscaData,
508                                                                                                            List<String> pathKeys,
509                                                                                                            JsonPresentationFields mapKeyField) {
510         List<T> toscaDataList = new ArrayList<>();
511         toscaDataList.add(toscaData);
512         return updateToscaDataDeepElementsOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, pathKeys, mapKeyField);
513     }
514
515     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsOfToscaElement(String toscaElementUid,
516                                                                                                             EdgeLabelEnum edgeLabel,
517                                                                                                             VertexTypeEnum vertexLabel,
518                                                                                                             List<T> toscaDataList,
519                                                                                                             List<String> pathKeys,
520                                                                                                             JsonPresentationFields mapKeyField) {
521         StorageOperationStatus statusRes = null;
522         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
523         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
524         if (getToscaElementRes.isRight()) {
525             JanusGraphOperationStatus status = getToscaElementRes.right().value();
526             CommonUtility
527                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
528             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
529         }
530         if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
531             statusRes = updateToscaDataDeepElementsOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys,
532                 mapKeyField);
533         }
534         if (statusRes == null) {
535             statusRes = StorageOperationStatus.OK;
536         }
537         return statusRes;
538     }
539
540     StorageOperationStatus overrideToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
541                                                            Map<String, ? extends ToscaDataDefinition> toscaData) {
542         return janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse).left()
543             .bind(graphVertex -> overrideToscaElementData(graphVertex, toscaData, edgeLabel))
544             .either(graphVertex -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
545     }
546
547     private Either<GraphVertex, JanusGraphOperationStatus> overrideToscaElementData(GraphVertex toscaElement,
548                                                                                     Map<String, ? extends ToscaDataDefinition> toscaData,
549                                                                                     EdgeLabelEnum edgeLabelEnum) {
550         return janusGraphDao.getChildVertex(toscaElement, edgeLabelEnum, JsonParseFlagEnum.ParseJson).left()
551             .bind(dataVertex -> overrideToscaElementData(dataVertex, toscaElement, toscaData, edgeLabelEnum)).right().map(
552                 err -> logAndReturn(err, "failed to override tosca data for element {} of type {}. status: {}", toscaElement.getUniqueId(),
553                     edgeLabelEnum, err));
554     }
555
556     private Either<GraphVertex, JanusGraphOperationStatus> overrideToscaElementData(GraphVertex dataElement, GraphVertex toscaElement,
557                                                                                     Map<String, ? extends ToscaDataDefinition> toscaData,
558                                                                                     EdgeLabelEnum edgeLabelEnum) {
559         dataElement.setJson(toscaData);
560         return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabelEnum);
561     }
562
563     /**
564      * Adds list of tosca data deep elements to tosca element with specified uid according received labels
565      *
566      * @param toscaElementUid
567      * @param edgeLabel
568      * @param vertexLabel
569      * @param toscaDataList
570      * @param pathKeys
571      * @param mapKeyField
572      * @return
573      */
574     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsToToscaElement(String toscaElementUid,
575                                                                                                          EdgeLabelEnum edgeLabel,
576                                                                                                          VertexTypeEnum vertexLabel,
577                                                                                                          List<T> toscaDataList, List<String> pathKeys,
578                                                                                                          JsonPresentationFields mapKeyField) {
579         StorageOperationStatus statusRes = null;
580         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
581         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
582         if (getToscaElementRes.isRight()) {
583             JanusGraphOperationStatus status = getToscaElementRes.right().value();
584             CommonUtility
585                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
586             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
587         }
588         if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
589             statusRes = addToscaDataDeepElementsToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, pathKeys,
590                 mapKeyField);
591         }
592         if (statusRes == null) {
593             statusRes = StorageOperationStatus.OK;
594         }
595         return statusRes;
596     }
597
598     public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockOfToscaElement(String toscaElementUid,
599                                                                                                                  EdgeLabelEnum edgeLabel,
600                                                                                                                  VertexTypeEnum vertexLabel,
601                                                                                                                  String key) {
602         StorageOperationStatus statusRes = null;
603         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
604         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
605         if (getToscaElementRes.isRight()) {
606             JanusGraphOperationStatus status = getToscaElementRes.right().value();
607             CommonUtility
608                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
609             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
610         }
611         if (statusRes == null) {
612             statusRes = deleteToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, key);
613         }
614         if (statusRes == null) {
615             statusRes = StorageOperationStatus.OK;
616         }
617         return statusRes;
618     }
619
620     public <T extends ToscaDataDefinition> StorageOperationStatus deleteToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
621                                                                                                                  EdgeLabelEnum edgeLabel,
622                                                                                                                  VertexTypeEnum vertexLabel,
623                                                                                                                  String key) {
624         StorageOperationStatus result = null;
625         GraphVertex toscaDataVertex = null;
626         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
627             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
628         if (toscaDataVertexRes.isRight()) {
629             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
630             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
631                 toscaElement.getUniqueId(), edgeLabel, status);
632             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
633         }
634         if (result == null) {
635             toscaDataVertex = toscaDataVertexRes.left().value();
636             result = deleteDeepElementsBlock(toscaDataVertex, key);
637         }
638         if (result == null) {
639             Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
640             if (updateOrCopyRes.isRight()) {
641                 JanusGraphOperationStatus status = updateOrCopyRes.right().value();
642                 CommonUtility
643                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca data block {} from the tosca element {}. Status is {}. ",
644                         edgeLabel, toscaElement.getUniqueId(), status);
645                 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
646             }
647         }
648         if (result == null) {
649             result = StorageOperationStatus.OK;
650         }
651         return result;
652     }
653
654     @SuppressWarnings("rawtypes")
655     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(String toscaElementUid,
656                                                                                                               EdgeLabelEnum edgeLabel,
657                                                                                                               VertexTypeEnum vertexLabel,
658                                                                                                               MapDataDefinition toscaDataMap,
659                                                                                                               String key) {
660         StorageOperationStatus statusRes = null;
661         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
662         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
663         if (getToscaElementRes.isRight()) {
664             JanusGraphOperationStatus status = getToscaElementRes.right().value();
665             CommonUtility
666                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
667             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
668         }
669         if (statusRes == null && toscaDataMap != null) {
670             statusRes = addToscaDataDeepElementsBlockToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataMap, key);
671         }
672         if (statusRes == null) {
673             statusRes = StorageOperationStatus.OK;
674         }
675         return statusRes;
676     }
677
678     @SuppressWarnings("rawtypes")
679     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
680                                                                                                               EdgeLabelEnum edgeLabel,
681                                                                                                               VertexTypeEnum vertexLabel,
682                                                                                                               MapDataDefinition toscaDataMap,
683                                                                                                               String key) {
684         StorageOperationStatus result = null;
685         GraphVertex toscaDataVertex = null;
686         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
687             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
688         if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
689             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
690             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
691                 toscaElement.getUniqueId(), edgeLabel, status);
692             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
693         }
694         if (result == null && toscaDataVertexRes.isLeft()) {
695             toscaDataVertex = toscaDataVertexRes.left().value();
696             result = addDeepElementsBlock(toscaDataVertex, toscaDataMap, key);
697         }
698         if (result == null) {
699             if (toscaDataVertex != null) {
700                 Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
701                 if (updateOrCopyRes.isRight()) {
702                     JanusGraphOperationStatus status = updateOrCopyRes.right().value();
703                     CommonUtility
704                         .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel,
705                             toscaElement.getUniqueId(), status);
706                     result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
707                 }
708             } else {
709                 Map<String, MapDataDefinition> data = new HashMap<>();
710                 data.put(key, toscaDataMap);
711                 Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, data);
712                 if (createRes.isRight()) {
713                     StorageOperationStatus status = createRes.right().value();
714                     CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to assosiate tosca data {} of the tosca element {}. Status is {}. ",
715                         edgeLabel, toscaElement.getUniqueId(), status);
716                     result = status;
717                 }
718             }
719         }
720         if (result == null) {
721             result = StorageOperationStatus.OK;
722         }
723         return result;
724     }
725
726     /**
727      * @param toscaElementId the id of the tosca element data container
728      * @param edgeLabel      the edge label of the data type to update
729      * @param toscaDataMap   the data to update
730      * @param key            the key in the json object where the map object block resides
731      * @return the status of the update operation
732      */
733     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(String toscaElementId,
734                                                                                                                  EdgeLabelEnum edgeLabel,
735                                                                                                                  MapDataDefinition<T> toscaDataMap,
736                                                                                                                  String key) {
737         return janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse)
738             .either(toscaElement -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, edgeLabel, toscaDataMap, key),
739                 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
740     }
741
742     private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataDeepElementsBlockToToscaElement(GraphVertex toscaElement,
743                                                                                                                   EdgeLabelEnum edgeLabel,
744                                                                                                                   MapDataDefinition<T> toscaDataMap,
745                                                                                                                   String key) {
746         return janusGraphDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson).left()
747             .bind(dataVertex -> updateToscaDataDeepElementsBlockToToscaElement(toscaElement, dataVertex, edgeLabel, toscaDataMap, key))
748             .either(updatedVertex -> StorageOperationStatus.OK, DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
749     }
750
751     private <T extends ToscaDataDefinition> Either<GraphVertex, JanusGraphOperationStatus> updateToscaDataDeepElementsBlockToToscaElement(
752         GraphVertex toscaElement, GraphVertex dataElement, EdgeLabelEnum edgeLabel, MapDataDefinition<T> toscaDataMap, String key) {
753         Map<String, T> mapToscaDataDefinition = toscaDataMap.getMapToscaDataDefinition();
754         updateDeepElements(dataElement, mapToscaDataDefinition, Collections.singletonList(key));
755         return updateOrCopyOnUpdate(dataElement, toscaElement, edgeLabel).right().map(
756             err -> logAndReturn(err, "failed while trying to update data vertex from tosca element {}, of type {} . status {}",
757                 toscaElement.getUniqueId(), edgeLabel, err));
758     }
759
760     /**
761      * Updates tosca data element of tosca element by specified uid according received labels
762      *
763      * @param toscaElementUid
764      * @param edgeLabel
765      * @param vertexLabel
766      * @param toscaData
767      * @param mapKeyField
768      * @return
769      */
770     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
771                                                                                                 VertexTypeEnum vertexLabel, T toscaData,
772                                                                                                 JsonPresentationFields mapKeyField) {
773         List<T> toscaDataList = new ArrayList<>();
774         toscaDataList.add(toscaData);
775         return updateToscaDataOfToscaElement(toscaElementUid, edgeLabel, vertexLabel, toscaDataList, mapKeyField);
776     }
777
778     /**
779      * Updates list of tosca data elements belonging to tosca element with specified uid according received labels
780      *
781      * @param toscaElementUid
782      * @param edgeLabel
783      * @param vertexLabel
784      * @param toscaDataList
785      * @param mapKeyField
786      * @return
787      */
788     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
789                                                                                                 VertexTypeEnum vertexLabel, List<T> toscaDataList,
790                                                                                                 JsonPresentationFields mapKeyField) {
791         StorageOperationStatus statusRes = null;
792         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
793         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
794         if (getToscaElementRes.isRight()) {
795             JanusGraphOperationStatus status = getToscaElementRes.right().value();
796             CommonUtility
797                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
798             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
799         }
800         if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
801             statusRes = updateToscaDataOfToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
802         }
803         if (statusRes == null) {
804             statusRes = StorageOperationStatus.OK;
805         }
806         return statusRes;
807     }
808
809     /**
810      * Adds list of tosca data elements to tosca element with specified uid according received labels
811      *
812      * @param toscaElementUid
813      * @param edgeLabel
814      * @param vertexLabel
815      * @param toscaDataList
816      * @param mapKeyField
817      * @return
818      */
819     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(String toscaElementUid, EdgeLabelEnum edgeLabel,
820                                                                                              VertexTypeEnum vertexLabel, List<T> toscaDataList,
821                                                                                              JsonPresentationFields mapKeyField) {
822         StorageOperationStatus statusRes = null;
823         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
824         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
825         if (getToscaElementRes.isRight()) {
826             JanusGraphOperationStatus status = getToscaElementRes.right().value();
827             CommonUtility
828                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
829             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
830         }
831         if (statusRes == null && CollectionUtils.isNotEmpty(toscaDataList)) {
832             statusRes = addToscaDataToToscaElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, toscaDataList, mapKeyField);
833         }
834         if (statusRes == null) {
835             statusRes = StorageOperationStatus.OK;
836         }
837         return statusRes;
838     }
839
840     /**
841      * Converts recieved map of tosca data elements to list and adds it to tosca element according received labels
842      *
843      * @param toscaElement
844      * @param edgeLabel
845      * @param vertexLabel
846      * @param toscaDataMap
847      * @param mapKeyField
848      * @return
849      */
850     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
851                                                                                              VertexTypeEnum vertexLabel, Map<String, T> toscaDataMap,
852                                                                                              JsonPresentationFields mapKeyField) {
853         return addToscaDataToToscaElement(toscaElement, edgeLabel, vertexLabel, toscaDataMap.values().stream().collect(Collectors.toList()),
854             mapKeyField);
855     }
856
857     /**
858      * Adds list of tosca data elements to tosca element according received labels
859      *
860      * @param toscaElement
861      * @param edgeLabel
862      * @param vertexLabel
863      * @param toscaDataList
864      * @param mapKeyField
865      * @return
866      */
867     public <T extends ToscaDataDefinition> StorageOperationStatus addToscaDataToToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
868                                                                                              VertexTypeEnum vertexLabel, List<T> toscaDataList,
869                                                                                              JsonPresentationFields mapKeyField) {
870         return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, false);
871     }
872
873     /**
874      * Updates list of tosca data elements belonging to tosca element according received labels
875      *
876      * @param toscaElement
877      * @param edgeLabel
878      * @param vertexLabel
879      * @param toscaDataList
880      * @param mapKeyField
881      * @return
882      */
883     public <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataOfToscaElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
884                                                                                                 VertexTypeEnum vertexLabel, List<T> toscaDataList,
885                                                                                                 JsonPresentationFields mapKeyField) {
886         return updateOrAddToscaData(toscaElement, edgeLabel, vertexLabel, toscaDataList, mapKeyField, true);
887     }
888
889     public boolean hasEdgeOfType(GraphVertex toscaElement, EdgeLabelEnum edgeLabel) {
890         Either<GraphVertex, JanusGraphOperationStatus> vertex = janusGraphDao.getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
891         return vertex.isLeft();
892     }
893
894     @SuppressWarnings("unchecked")
895     private <T extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
896                                                                                         VertexTypeEnum vertexLabel, List<T> toscaDataList,
897                                                                                         JsonPresentationFields mapKeyField, boolean isUpdate) {
898         StorageOperationStatus result = null;
899         GraphVertex toscaDataVertex = null;
900         Map<String, T> existingToscaDataMap = null;
901         Either<Map<String, T>, StorageOperationStatus> validateRes = null;
902         Map<String, T> mergedToscaDataMap;
903         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
904             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
905         if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
906             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
907             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
908                 toscaElement.getUniqueId(), edgeLabel, status);
909             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
910         }
911         if (result == null) {
912             if (toscaDataVertexRes.isLeft()) {
913                 toscaDataVertex = toscaDataVertexRes.left().value();
914                 existingToscaDataMap = (Map<String, T>) toscaDataVertex.getJson();
915             }
916             validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingToscaDataMap, isUpdate);
917             if (validateRes.isRight()) {
918                 result = validateRes.right().value();
919                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ",
920                     toscaElement.getUniqueId(), edgeLabel, result);
921             }
922         }
923         if (result == null) {
924             mergedToscaDataMap = validateRes.left().value();
925             result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, mergedToscaDataMap);
926         }
927         if (result == null) {
928             result = StorageOperationStatus.OK;
929         }
930         return result;
931     }
932
933     <T extends ToscaDataDefinition> StorageOperationStatus updateFullToscaData(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
934                                                                                VertexTypeEnum vertexLabel, Map<String, T> toscaData) {
935         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
936             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
937         if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
938             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
939             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
940                 toscaElement.getUniqueId(), edgeLabel, status);
941             return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
942         }
943         GraphVertex toscaDataVertex = null;
944         if (toscaDataVertexRes.isLeft()) {
945             toscaDataVertex = toscaDataVertexRes.left().value();
946         }
947         StorageOperationStatus result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaData);
948         return result == null ? StorageOperationStatus.OK : result;
949     }
950
951     @SuppressWarnings({"rawtypes", "unchecked"})
952     private <T, K extends ToscaDataDefinition> StorageOperationStatus updateOrAddToscaDataDeepElement(GraphVertex toscaElement,
953                                                                                                       EdgeLabelEnum edgeLabel,
954                                                                                                       VertexTypeEnum vertexLabel,
955                                                                                                       List<K> toscaDataList, List<String> pathKeys,
956                                                                                                       JsonPresentationFields mapKeyField,
957                                                                                                       boolean isUpdate) {
958         StorageOperationStatus result = null;
959         GraphVertex toscaDataVertex = null;
960         Map<String, K> existingDeepElementsMap = null;
961         Either<Map<String, K>, StorageOperationStatus> validateRes = null;
962         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
963             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
964         if (toscaDataVertexRes.isRight() && toscaDataVertexRes.right().value() != JanusGraphOperationStatus.NOT_FOUND) {
965             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
966             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
967                 toscaElement.getUniqueId(), edgeLabel, status);
968             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
969         }
970         if (result == null) {
971             if (toscaDataVertexRes.isLeft()) {
972                 toscaDataVertex = toscaDataVertexRes.left().value();
973                 existingDeepElementsMap = getDeepElements(toscaDataVertex, pathKeys);
974             }
975             validateRes = validateMergeToscaData(toscaElement, toscaDataList, mapKeyField, existingDeepElementsMap, isUpdate);
976             if (validateRes.isRight()) {
977                 result = validateRes.right().value();
978                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed validate tosca data upon adding to tosca element {}. Status is {}. ",
979                     toscaElement.getUniqueId(), edgeLabel, result);
980             }
981         }
982         if (result == null) {
983             updateDeepElements(toscaDataVertex, validateRes.left().value(), pathKeys);
984             Map<String, K> toscaDataToHandle;
985             if (toscaDataVertex == null) {
986                 toscaDataToHandle = new HashMap<>();
987                 Map<String, K> currMap = toscaDataToHandle;
988                 for (int i = 1; i < pathKeys.size() - 1; ++i) {
989                     currMap.put(pathKeys.get(i), (K) new MapDataDefinition());
990                     currMap = (Map<String, K>) ((MapDataDefinition) currMap).getMapToscaDataDefinition().get(pathKeys.get(i));
991                 }
992                 toscaDataToHandle.put(pathKeys.get(pathKeys.size() - 1), (K) new MapDataDefinition(validateRes.left().value()));
993             } else {
994                 toscaDataToHandle = (Map<String, K>) toscaDataVertex.getJson();
995             }
996             result = handleToscaData(toscaElement, vertexLabel, edgeLabel, toscaDataVertex, toscaDataToHandle);
997         }
998         if (result == null) {
999             result = StorageOperationStatus.OK;
1000         }
1001         return result;
1002     }
1003
1004     @SuppressWarnings({"rawtypes", "unchecked"})
1005     private <T, K extends ToscaDataDefinition> void updateDeepElements(GraphVertex toscaDataVertex, Map<String, K> mergedDeepElementMap,
1006                                                                        List<String> pathKeys) {
1007         if (toscaDataVertex != null && MapUtils.isNotEmpty(mergedDeepElementMap)) {
1008             Map<String, MapDataDefinition> currMap = (Map<String, MapDataDefinition>) toscaDataVertex.getJson();
1009             if (!currMap.containsKey(pathKeys.get(0))) {
1010                 currMap.put(pathKeys.get(0), new MapDataDefinition<>());
1011             }
1012             Object object = currMap.get(pathKeys.get(0));
1013             MapDataDefinition currDeepElement = null;
1014             if (object instanceof MapDataDefinition) {
1015                 currDeepElement = (MapDataDefinition) object;
1016             } else {
1017                 currDeepElement = new MapDataDefinition(currMap);
1018             }
1019             for (int i = 1; i < pathKeys.size(); ++i) {
1020                 if (currDeepElement.findByKey(pathKeys.get(i)) == null) {
1021                     currDeepElement.put(pathKeys.get(i), new MapDataDefinition<>());
1022                 }
1023                 currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
1024             }
1025             if (currDeepElement != null) {
1026                 for (Map.Entry<String, K> elementEntry : mergedDeepElementMap.entrySet()) {
1027                     currDeepElement.put(elementEntry.getKey(), elementEntry.getValue());
1028                 }
1029             }
1030         }
1031     }
1032
1033     @SuppressWarnings({"unchecked", "rawtypes"})
1034     private <T, K extends ToscaDataDefinition> Map<String, K> getDeepElements(GraphVertex toscaDataVertex, List<String> pathKeys) {
1035         Map<String, K> result = null;
1036         Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1037         MapDataDefinition currDeepElement = (MapDataDefinition) currMap.get(pathKeys.get(0));
1038         for (int i = 1; i < pathKeys.size(); ++i) {
1039             currDeepElement = (MapDataDefinition) currDeepElement.findByKey(pathKeys.get(i));
1040         }
1041         if (currDeepElement != null) {
1042             result = (Map<String, K>) currDeepElement.getMapToscaDataDefinition();
1043         }
1044         return result;
1045     }
1046
1047     @SuppressWarnings("unchecked")
1048     private <T extends ToscaDataDefinition> StorageOperationStatus addDeepElementsBlock(GraphVertex toscaDataVertex, T toscaDataBlock, String key) {
1049         StorageOperationStatus result = null;
1050         Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1051         if (currMap.containsKey(key)) {
1052             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1053                 "Failed to add block of deep tosca data elements by label {}." + " The block element with the same key {} already exists. ",
1054                 toscaDataVertex.getLabel(), key);
1055             result = StorageOperationStatus.ENTITY_ALREADY_EXISTS;
1056         }
1057         if (result == null) {
1058             currMap.put(key, toscaDataBlock);
1059         }
1060         return result;
1061     }
1062
1063     @SuppressWarnings("unchecked")
1064     private <T extends ToscaDataDefinition> StorageOperationStatus deleteDeepElementsBlock(GraphVertex toscaDataVertex, String key) {
1065         StorageOperationStatus result = null;
1066         Map<String, T> currMap = (Map<String, T>) toscaDataVertex.getJson();
1067         if (!currMap.containsKey(key)) {
1068             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1069                 "Failed to delete block of deep tosca data elements by label {}." + " The block element with the same key {} doesn't exist. ",
1070                 toscaDataVertex.getLabel(), key);
1071             result = StorageOperationStatus.NOT_FOUND;
1072         }
1073         if (result == null) {
1074             currMap.remove(key);
1075         }
1076         return null;
1077     }
1078
1079     /**
1080      * Removes tosca data vertex belonging to tosca element specified by uid according label
1081      *
1082      * @param toscaElementUid
1083      * @param edgeLabel
1084      * @param vertexLabel
1085      * @return
1086      */
1087     public StorageOperationStatus removeToscaData(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
1088         StorageOperationStatus statusRes = StorageOperationStatus.OK;
1089         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1090         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1091         if (getToscaElementRes.isRight()) {
1092             JanusGraphOperationStatus status = getToscaElementRes.right().value();
1093             CommonUtility
1094                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1095             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1096         }
1097         if (statusRes == StorageOperationStatus.OK) {
1098             statusRes = removeToscaDataVertex(getToscaElementRes.left().value(), edgeLabel, vertexLabel);
1099         }
1100         return statusRes;
1101     }
1102
1103     /**
1104      * Removes tosca data vertex belonging to tosca element according label
1105      *
1106      * @param toscaElement
1107      * @param edgeLabel
1108      * @param vertexLabel
1109      * @return
1110      */
1111     public StorageOperationStatus removeToscaDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel) {
1112         StorageOperationStatus result = null;
1113         GraphVertex toscaDataVertex = null;
1114         Iterator<Edge> edges = null;
1115         int edgeCounter = 0;
1116         Edge edge = null;
1117         Edge edgeToDelete = null;
1118         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1119             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1120         if (toscaDataVertexRes.isRight()) {
1121             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1122             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1123                 toscaElement.getUniqueId(), edgeLabel, status);
1124             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1125         }
1126         if (result == null) {
1127             toscaDataVertex = toscaDataVertexRes.left().value();
1128             edges = toscaDataVertex.getVertex().edges(Direction.IN);
1129             if (edges == null || !edges.hasNext()) {
1130                 result = StorageOperationStatus.NOT_FOUND;
1131                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1132                     toscaElement.getUniqueId(), edgeLabel, result);
1133             }
1134         }
1135         if (result == null) {
1136             if (edges != null) {
1137                 while (edges.hasNext()) {
1138                     ++edgeCounter;
1139                     edge = edges.next();
1140                     if (edge.outVertex().id().equals(toscaElement.getVertex().id())) {
1141                         edgeToDelete = edge;
1142                         break;
1143                     }
1144                 }
1145             }
1146             if (edgeToDelete == null) {
1147                 result = StorageOperationStatus.NOT_FOUND;
1148                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_REMOVE_TOSCA_DATA_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1149                     toscaElement.getUniqueId(), edgeLabel, result);
1150             }
1151         }
1152         if (result == null) {
1153             if (edgeCounter > 1 && edgeToDelete != null) {
1154                 edgeToDelete.remove();
1155             } else {
1156                 toscaDataVertex.getVertex().remove();
1157             }
1158         }
1159         if (result == null) {
1160             result = StorageOperationStatus.OK;
1161         }
1162         return result;
1163     }
1164
1165     /**
1166      * Deletes tosca data elements belonging to tosca element specified by uid according label
1167      *
1168      * @param toscaElementUid
1169      * @param edgeLabel
1170      * @param uniqueKeys
1171      * @return
1172      */
1173     public StorageOperationStatus deleteToscaDataElements(String toscaElementUid, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
1174         StorageOperationStatus statusRes = StorageOperationStatus.OK;
1175         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1176         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1177         if (getToscaElementRes.isRight()) {
1178             JanusGraphOperationStatus status = getToscaElementRes.right().value();
1179             CommonUtility
1180                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1181             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1182         }
1183         if (statusRes == StorageOperationStatus.OK) {
1184             statusRes = deleteToscaDataElements(getToscaElementRes.left().value(), edgeLabel, uniqueKeys);
1185         }
1186         return statusRes;
1187     }
1188
1189     /**
1190      * Deletes tosca data element belonging to tosca element specified by uid according label
1191      *
1192      * @param toscaElementUid
1193      * @param edgeLabel
1194      * @param vertexLabel
1195      * @param uniqueKey
1196      * @param mapKeyField
1197      * @return
1198      */
1199     public StorageOperationStatus deleteToscaDataElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1200                                                          String uniqueKey, JsonPresentationFields mapKeyField) {
1201         StorageOperationStatus statusRes = StorageOperationStatus.OK;
1202         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1203         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1204         if (getToscaElementRes.isRight()) {
1205             JanusGraphOperationStatus status = getToscaElementRes.right().value();
1206             CommonUtility
1207                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1208             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1209         }
1210         if (statusRes == StorageOperationStatus.OK) {
1211             statusRes = deleteToscaDataElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, mapKeyField);
1212         }
1213         return statusRes;
1214     }
1215
1216     /**
1217      * Deletes tosca data deep element belonging to tosca element specified by uid according label
1218      *
1219      * @param toscaElementUid
1220      * @param edgeLabel
1221      * @param vertexLabel
1222      * @param uniqueKey
1223      * @param pathKeys
1224      * @param mapKeyField
1225      * @return
1226      */
1227     public StorageOperationStatus deleteToscaDataDeepElement(String toscaElementUid, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1228                                                              String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
1229         StorageOperationStatus statusRes = StorageOperationStatus.OK;
1230         Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes;
1231         getToscaElementRes = janusGraphDao.getVertexById(toscaElementUid, JsonParseFlagEnum.NoParse);
1232         if (getToscaElementRes.isRight()) {
1233             JanusGraphOperationStatus status = getToscaElementRes.right().value();
1234             CommonUtility
1235                 .addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_TOSCA_ELEMENT_UPON_ADDING_THE_PROPERTIES_STATUS_IS, toscaElementUid, status);
1236             statusRes = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1237         }
1238         if (statusRes == StorageOperationStatus.OK) {
1239             statusRes = deleteToscaDataDeepElement(getToscaElementRes.left().value(), edgeLabel, vertexLabel, uniqueKey, pathKeys, mapKeyField);
1240         }
1241         return statusRes;
1242     }
1243
1244     /**
1245      * Deletes tosca data deep element belonging to tosca element according label
1246      *
1247      * @param toscaElement
1248      * @param edgeLabel
1249      * @param vertexLabel
1250      * @param uniqueKey
1251      * @param pathKeys
1252      * @param mapKeyField
1253      * @return
1254      */
1255     public StorageOperationStatus deleteToscaDataDeepElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1256                                                              String uniqueKey, List<String> pathKeys, JsonPresentationFields mapKeyField) {
1257         List<String> uniqueKeys = new ArrayList<>();
1258         uniqueKeys.add(uniqueKey);
1259         return deleteToscaDataDeepElements(toscaElement, edgeLabel, vertexLabel, uniqueKeys, pathKeys, mapKeyField);
1260     }
1261
1262     public StorageOperationStatus deleteToscaDataDeepElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1263                                                               List<String> uniqueKeys, List<String> pathKeys, JsonPresentationFields mapKeyField) {
1264         StorageOperationStatus result = null;
1265         GraphVertex toscaDataVertex;
1266         Map<String, ToscaDataDefinition> existingToscaDataMap = null;
1267         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1268             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1269         if (toscaDataVertexRes.isRight()) {
1270             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1271             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1272                 toscaElement.getUniqueId(), edgeLabel, status);
1273             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1274         }
1275         if (result == null) {
1276             toscaDataVertex = toscaDataVertexRes.left().value();
1277             existingToscaDataMap = getDeepElements(toscaDataVertexRes.left().value(), pathKeys);
1278             result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
1279         }
1280         if (result == null) {
1281             result = StorageOperationStatus.OK;
1282         }
1283         return result;
1284     }
1285
1286     private StorageOperationStatus deleteElementsFromDataVertex(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys,
1287                                                                 GraphVertex toscaDataVertex, Map<String, ToscaDataDefinition> existingToscaDataMap) {
1288         StorageOperationStatus result;
1289         for (String uniqueKey : uniqueKeys) {
1290             result = removeKeyFromDataVertex(uniqueKey, existingToscaDataMap);
1291             if (result != StorageOperationStatus.OK) {
1292                 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1293                     "Failed to delete tosca data element of the tosca element {} by label {}. Status is {}. ", toscaElement.getUniqueId(), edgeLabel,
1294                     result);
1295                 break;
1296             }
1297         }
1298         result = updateToscaDataElement(toscaElement, edgeLabel, toscaDataVertex);
1299         return result;
1300     }
1301
1302     /**
1303      * Deletes tosca data element belonging to tosca element according label
1304      *
1305      * @param toscaElement
1306      * @param edgeLabel
1307      * @param vertexLabel
1308      * @param uniqueKey
1309      * @param mapKeyField
1310      * @return
1311      */
1312     public StorageOperationStatus deleteToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, VertexTypeEnum vertexLabel,
1313                                                          String uniqueKey, JsonPresentationFields mapKeyField) {
1314         List<String> uniqueKeys = new ArrayList<>();
1315         uniqueKeys.add(uniqueKey);
1316         return deleteToscaDataElements(toscaElement, edgeLabel, uniqueKeys);
1317     }
1318
1319     @SuppressWarnings("unchecked")
1320 /**
1321  * Deletes tosca data elements belonging to tosca element according label
1322  * @param toscaElement
1323  * @param edgeLabel
1324  * @param uniqueKeys
1325  * @return
1326  */
1327     public StorageOperationStatus deleteToscaDataElements(GraphVertex toscaElement, EdgeLabelEnum edgeLabel, List<String> uniqueKeys) {
1328         StorageOperationStatus result = null;
1329         GraphVertex toscaDataVertex;
1330         Map<String, ToscaDataDefinition> existingToscaDataMap;
1331         Either<GraphVertex, JanusGraphOperationStatus> toscaDataVertexRes = janusGraphDao
1332             .getChildVertex(toscaElement, edgeLabel, JsonParseFlagEnum.ParseJson);
1333         if (toscaDataVertexRes.isRight()) {
1334             JanusGraphOperationStatus status = toscaDataVertexRes.right().value();
1335             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_CHILD_VERTEX_OF_THE_TOSCA_ELEMENT_BY_LABEL_STATUS_IS,
1336                 toscaElement.getUniqueId(), edgeLabel, status);
1337             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(toscaDataVertexRes.right().value());
1338         }
1339         if (result == null) {
1340             toscaDataVertex = toscaDataVertexRes.left().value();
1341             existingToscaDataMap = (Map<String, ToscaDataDefinition>) toscaDataVertex.getJson();
1342             result = deleteElementsFromDataVertex(toscaElement, edgeLabel, uniqueKeys, toscaDataVertex, existingToscaDataMap);
1343         }
1344         if (result == null) {
1345             result = StorageOperationStatus.OK;
1346         }
1347         return result;
1348     }
1349
1350     /**
1351      * Adds the map data entry to the graph vertex of the specified type, related with the specified edge to the component specified by ID
1352      *
1353      * @param componentId    The uniqueId of the component
1354      * @param vertexTypeEnum The type of the vertex
1355      * @param edgeLabelEnum  The type of the edge
1356      * @param mapDataEntry   The map data entry
1357      * @param <T             extends MapDataDefinition>
1358      * @return The status of the operation result
1359      */
1360     public <T extends MapDataDefinition> StorageOperationStatus addElementToComponent(String componentId, VertexTypeEnum vertexTypeEnum,
1361                                                                                       EdgeLabelEnum edgeLabelEnum,
1362                                                                                       Map.Entry<String, T> mapDataEntry) {
1363         if (MapUtils.isNotEmpty(mapDataEntry.getValue().getMapToscaDataDefinition())) {
1364             return addToscaDataDeepElementsBlockToToscaElement(componentId, edgeLabelEnum, vertexTypeEnum, mapDataEntry.getValue(),
1365                 mapDataEntry.getKey());
1366         }
1367         return StorageOperationStatus.OK;
1368     }
1369
1370     private <T extends ToscaDataDefinition> StorageOperationStatus updateToscaDataElement(GraphVertex toscaElement, EdgeLabelEnum edgeLabel,
1371                                                                                           GraphVertex toscaDataVertex) {
1372         StorageOperationStatus result = StorageOperationStatus.OK;
1373         Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
1374         if (updateOrCopyRes.isRight()) {
1375             result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(updateOrCopyRes.right().value());
1376             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca data {} of the tosca element {}. Status is {}. ", edgeLabel,
1377                 toscaElement.getUniqueId(), result);
1378         }
1379         return result;
1380     }
1381
1382     private <T extends ToscaDataDefinition> StorageOperationStatus removeKeyFromDataVertex(String uniqueKey, Map<String, T> existingToscaDataMap) {
1383         if (!existingToscaDataMap.containsKey(uniqueKey)) {
1384             return StorageOperationStatus.NOT_FOUND;
1385         }
1386         existingToscaDataMap.remove(uniqueKey);
1387         return StorageOperationStatus.OK;
1388     }
1389
1390     <K extends ToscaDataDefinition> StorageOperationStatus handleToscaData(GraphVertex toscaElement, VertexTypeEnum vertexLabel,
1391                                                                            EdgeLabelEnum edgeLabel, GraphVertex toscaDataVertex,
1392                                                                            Map<String, K> mergedToscaDataMap) {
1393         StorageOperationStatus result = StorageOperationStatus.OK;
1394         if (toscaDataVertex == null) {
1395             if (MapUtils.isEmpty(mergedToscaDataMap)) {
1396                 //If no new data and this vertex type does not exist, return
1397                 return result;
1398             }
1399             Either<GraphVertex, StorageOperationStatus> createRes = associateElementToData(toscaElement, vertexLabel, edgeLabel, mergedToscaDataMap);
1400             if (createRes.isRight()) {
1401                 StorageOperationStatus status = createRes.right().value();
1402                 CommonUtility
1403                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate tosca data {} of the tosca element {}. Status is {}. ", edgeLabel,
1404                         toscaElement.getUniqueId(), status);
1405                 result = status;
1406             }
1407         } else {
1408             if (MapUtils.isEmpty(mergedToscaDataMap)) {
1409                 JanusGraphOperationStatus janusGraphOperationStatus = janusGraphDao.disassociateAndDeleteLast(toscaElement, Direction.OUT, edgeLabel);
1410                 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphOperationStatus);
1411             }
1412             toscaDataVertex.setJson(mergedToscaDataMap);
1413             Either<GraphVertex, JanusGraphOperationStatus> updateOrCopyRes = updateOrCopyOnUpdate(toscaDataVertex, toscaElement, edgeLabel);
1414             if (updateOrCopyRes.isRight()) {
1415                 JanusGraphOperationStatus status = updateOrCopyRes.right().value();
1416                 CommonUtility
1417                     .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data {} to the tosca element {}. Status is {}. ", edgeLabel,
1418                         toscaElement.getUniqueId(), status);
1419                 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1420             }
1421         }
1422         return result;
1423     }
1424
1425     private <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> validateMergeToscaData(GraphVertex toscaElement,
1426                                                                                                                   List<T> toscaDataList,
1427                                                                                                                   JsonPresentationFields mapKeyField,
1428                                                                                                                   Map<String, T> existingToscaDataMap,
1429                                                                                                                   boolean isUpdate) {
1430         Map<String, T> mergedToscaDataMap = new HashMap<>();
1431         StorageOperationStatus status;
1432         Either<Map<String, T>, StorageOperationStatus> result = Either.left(mergedToscaDataMap);
1433         if (MapUtils.isNotEmpty(existingToscaDataMap)) {
1434             mergedToscaDataMap.putAll(existingToscaDataMap);
1435         }
1436         for (T toscaDataElement : toscaDataList) {
1437             status = handleToscaDataElement(toscaElement, mapKeyField, mergedToscaDataMap, toscaDataElement, isUpdate);
1438             if (status != StorageOperationStatus.OK) {
1439                 result = Either.right(status);
1440                 break;
1441             }
1442         }
1443         return result;
1444     }
1445
1446     private <T extends ToscaDataDefinition> StorageOperationStatus handleToscaDataElement(GraphVertex toscaElement,
1447                                                                                           JsonPresentationFields mapKeyField,
1448                                                                                           Map<String, T> mergedToscaDataMap, T toscaDataElement,
1449                                                                                           boolean isUpdate) {
1450         StorageOperationStatus status = StorageOperationStatus.OK;
1451         String currKey = (String) toscaDataElement.getToscaPresentationValue(mapKeyField);
1452         if (StringUtils.isEmpty(currKey) && toscaDataElement instanceof ListDataDefinition) {
1453             ToscaDataDefinition toscaDataDefinition = ((ListDataDefinition<? extends ToscaDataDefinition>) toscaDataElement)
1454                 .getListToscaDataDefinition().get(0);
1455             if (toscaDataDefinition != null) {
1456                 currKey = (String) toscaDataDefinition.getToscaPresentationValue(mapKeyField);
1457             }
1458         }
1459         if (StringUtils.isEmpty(currKey)) {
1460             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to add tosca data to tosca element {}. The key is empty. ");
1461             status = StorageOperationStatus.BAD_REQUEST;
1462         } else if (!isUpdate && mergedToscaDataMap.containsKey(currKey)) {
1463             CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1464                 "Failed to add tosca data to tosca element {}. The element with the same key {} already exists. ", toscaElement.getUniqueId(),
1465                 currKey);
1466             status = StorageOperationStatus.BAD_REQUEST;
1467         }
1468         mergedToscaDataMap.put(currKey, toscaDataElement);
1469         return status;
1470     }
1471
1472     protected GroupInstanceDataDefinition buildGroupInstanceDataDefinition(GroupDataDefinition group,
1473                                                                            ComponentInstanceDataDefinition componentInstance,
1474                                                                            Map<String, ArtifactDataDefinition> instDeplArtifMap) {
1475         String componentInstanceName = componentInstance.getName();
1476         Long creationDate = System.currentTimeMillis();
1477         GroupInstanceDataDefinition groupInstance = new GroupInstanceDataDefinition();
1478         String groupUid = group.getUniqueId();
1479         groupInstance.setGroupUid(groupUid);
1480         groupInstance.setType(group.getType());
1481         groupInstance.setCustomizationUUID(generateCustomizationUUID());
1482         groupInstance.setCreationTime(creationDate);
1483         groupInstance.setModificationTime(creationDate);
1484         groupInstance.setName(buildGroupInstanceName(componentInstanceName, group.getName()));
1485         groupInstance.setGroupName(group.getName());
1486         groupInstance.setNormalizedName(ValidationUtils.normalizeComponentInstanceName(groupInstance.getName()));
1487         groupInstance
1488             .setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(componentInstance.getUniqueId(), groupUid, groupInstance.getNormalizedName()));
1489         groupInstance.setArtifacts(group.getArtifacts());
1490         groupInstance.setArtifactsUuid(group.getArtifactsUuid());
1491         groupInstance.setProperties(group.getProperties());
1492         convertPropertiesToInstanceProperties(groupInstance.getProperties());
1493         groupInstance.setInvariantUUID(group.getInvariantUUID());
1494         groupInstance.setGroupUUID(group.getGroupUUID());
1495         groupInstance.setVersion(group.getVersion());
1496         return groupInstance;
1497     }
1498
1499     protected String buildGroupInstanceName(String instanceName, String groupName) {
1500         return ValidationUtils.normalizeComponentInstanceName(instanceName) + ".." + groupName;
1501     }
1502
1503     protected String generateCustomizationUUID() {
1504         return UUID.randomUUID().toString();
1505     }
1506
1507     protected void convertPropertiesToInstanceProperties(List<PropertyDataDefinition> properties) {
1508         properties.forEach(PropertyDataDefinition::convertPropertyDataToInstancePropertyData);
1509     }
1510
1511     private JanusGraphOperationStatus logAndReturn(JanusGraphOperationStatus janusGraphOperationStatus, String logMsg, Object... logParams) {
1512         log.debug(logMsg, logParams);
1513         return janusGraphOperationStatus;
1514     }
1515
1516     protected GraphVertex throwStorageException(JanusGraphOperationStatus status) {
1517         throw new StorageException(status);
1518     }
1519
1520     public void setHealingPipelineDao(HealingPipelineDao healingPipelineDao) {
1521         this.healingPipelineDao = healingPipelineDao;
1522     }
1523 }