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