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