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