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