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