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