[sdc] update to the current code base
[sdc.git] / catalog-model / src / main / java / org / openecomp / sdc / be / model / jsontitan / operations / ToscaElementLifecycleOperation.java
1 package org.openecomp.sdc.be.model.jsontitan.operations;
2
3 import java.util.ArrayList;
4 import java.util.EnumMap;
5 import java.util.HashMap;
6 import java.util.Iterator;
7 import java.util.List;
8 import java.util.Map;
9 import java.util.Optional;
10 import java.util.Map.Entry;
11 import java.util.stream.Collectors;
12
13 import org.apache.commons.collections.CollectionUtils;
14 import org.apache.commons.collections.MapUtils;
15 import org.apache.commons.lang.StringUtils;
16 import org.apache.commons.lang3.tuple.ImmutablePair;
17 import org.apache.tinkerpop.gremlin.structure.Direction;
18 import org.apache.tinkerpop.gremlin.structure.Edge;
19 import org.apache.tinkerpop.gremlin.structure.Vertex;
20
21 import org.openecomp.sdc.be.config.ConfigurationManager;
22 import org.openecomp.sdc.be.dao.api.ActionStatus;
23 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
24 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
25 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
26 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
27 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
28 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
29 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
30 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
38 import org.openecomp.sdc.be.datatypes.elements.MapDataDefinition;
39 import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
44 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
45 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
46 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
47 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
48 import org.openecomp.sdc.be.model.ArtifactDefinition;
49 import org.openecomp.sdc.be.model.ComponentParametersView;
50 import org.openecomp.sdc.be.model.DistributionStatusEnum;
51 import org.openecomp.sdc.be.model.GroupDefinition;
52 import org.openecomp.sdc.be.model.LifecycleStateEnum;
53 import org.openecomp.sdc.be.model.User;
54 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
55 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
56 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
57 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
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.api.ArtifactTypeEnum;
62 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
63 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
64 import org.openecomp.sdc.exception.ResponseFormat;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67
68 import fj.data.Either;
69
70 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
71
72 /**
73  * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
74  */
75 public class ToscaElementLifecycleOperation extends BaseOperation {
76
77         private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
78         public static final String VERSION_DELIMETER = ".";
79         public static final String VERSION_DELIMETER_REGEXP = "\\.";
80
81         private static Logger logger = LoggerFactory.getLogger(ToscaElementLifecycleOperation.class.getName());
82
83         /**
84          * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
85          * 
86          * @param currState
87          * @param toscaElementId
88          * @param modifierId
89          * @param ownerId
90          * @return
91          */
92         public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
93                 Either<GraphVertex, StorageOperationStatus> updateResult = null;
94                 Either<ToscaElement, StorageOperationStatus> result = null;
95                 Map<String, GraphVertex> vertices = null;
96                 ToscaElementOperation operation;
97                 try {
98                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
99                         if (getVerticesRes.isRight()) {
100                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
101                                 updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
102                         } else {
103                                 vertices = getVerticesRes.left().value();
104                                 updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
105                         }
106                         if (updateResult.isLeft()) {
107                                 ComponentParametersView componentParametersView = buildComponentParametersViewAfterCheckin();
108                                 operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
109                                 result = operation.getToscaElement(updateResult.left().value().getUniqueId(), componentParametersView);
110                                 if (result.isRight()) {
111                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
112                                 }
113                         } else {
114                                 result = Either.right(updateResult.right().value());
115                         }
116                 } catch (Exception e) {
117                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
118                 }
119                 return result;
120         }
121
122         /**
123          * Returns vertex presenting owner of tosca element specified by uniqueId
124          * 
125          * @param toscaElement
126          * @return
127          */
128         public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
129                 Either<User, StorageOperationStatus> result = null;
130                 GraphVertex toscaElement = null;
131                 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
132                 if (getToscaElementRes.isRight()) {
133                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
134                 }
135                 if (result == null) {
136                         toscaElement = getToscaElementRes.left().value();
137                         Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
138                         if (vertices == null || !vertices.hasNext()) {
139                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
140                         } else {
141                                 result = Either.left(convertToUser(vertices.next()));
142                         }
143                 }
144                 return result;
145         }
146
147         /**
148          * Returns vertex presenting owner of tosca element specified by uniqueId
149          * 
150          * @param toscaElement
151          * @return
152          */
153         public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
154                 Either<User, StorageOperationStatus> result = null;
155                 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
156                 if (vertices == null || !vertices.hasNext()) {
157                         result = Either.right(StorageOperationStatus.NOT_FOUND);
158                 } else {
159                         result = Either.left(convertToUser(vertices.next()));
160                 }
161                 return result;
162         }
163
164         /**
165          * Performs checkout of a tosca element
166          * 
167          * @param toscaElementId
168          * @param modifierId
169          * @param ownerId
170          * @param currState
171          * @return
172          */
173         public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
174                 Either<ToscaElement, StorageOperationStatus> result = null;
175                 Map<String, GraphVertex> vertices = null;
176                 try {
177                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
178                         if (getVerticesRes.isRight()) {
179                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
180                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
181                         }
182                         if (result == null) {
183                                 vertices = getVerticesRes.left().value();
184                                 // update previous component if not certified
185                                 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
186                                 if (status != StorageOperationStatus.OK) {
187                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
188                                         result = Either.right(status);
189                                 }
190                         }
191                         if (result == null) {
192                                 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
193                                 if (result.isRight()) {
194                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
195                                 }
196
197                         }
198                 } catch (Exception e) {
199                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
200                 }
201                 return result;
202         }
203
204         /**
205          * Performs undo checkout for tosca element
206          * 
207          * @param toscaElementId
208          * @return
209          */
210         public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
211                 Either<ToscaElement, StorageOperationStatus> result = null;
212                 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
213                 Iterator<Edge> nextVersionComponentIter = null;
214                 ToscaElementOperation operation;
215                 try {
216                         getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
217                         if (getToscaElementRes.isRight()) {
218                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
219                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
220                         }
221                         if (result == null && hasPreviousVersion(getToscaElementRes.left().value())) {
222                                 // find previous version
223                                 nextVersionComponentIter = getToscaElementRes.left().value().getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
224                                 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
225                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", getToscaElementRes.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
226                                         result = Either.right(StorageOperationStatus.NOT_FOUND);
227                                 }
228                                 if (result == null) {
229                                         StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(nextVersionComponentIter.next().outVertex());
230                                         if (updateOldResourceResult != StorageOperationStatus.OK) {
231                                                 result = Either.right(updateOldResourceResult);
232                                         }
233                                 }
234                         }
235                         if (result == null) {
236                                 operation = getToscaElementOperation(getToscaElementRes.left().value().getLabel());
237                                 result = operation.deleteToscaElement(getToscaElementRes.left().value());
238                         }
239                 } catch (Exception e) {
240                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
241                 }
242                 return result;
243         }
244
245         private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
246                 boolean hasPreviousVersion = true;
247                 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
248                 if (StringUtils.isEmpty(version) || version.equals("0.1"))
249                         hasPreviousVersion = false;
250                 return hasPreviousVersion;
251         }
252
253         /**
254          * Performs request certification for tosca element
255          * 
256          * @param toscaElementId
257          * @param modifierId
258          * @param ownerId
259          * @return
260          */
261         public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
262                 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
263                 Either<ToscaElement, StorageOperationStatus> result = null;
264                 GraphVertex toscaElement = null;
265                 GraphVertex modifier = null;
266                 GraphVertex owner;
267                 try {
268                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
269                         if (getVerticesRes.isRight()) {
270                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
271                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
272                         }
273                         if (result == null) {
274                                 toscaElement = getVerticesRes.left().value().get(toscaElementId);
275                                 modifier = getVerticesRes.left().value().get(modifierId);
276                                 owner = getVerticesRes.left().value().get(ownerId);
277
278                                 StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
279                                 if (status != StorageOperationStatus.OK) {
280                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
281                                 }
282                         }
283                         if (result == null) {
284                                 LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
285
286                                 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
287                                 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
288
289                                 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
290                                 if (resultUpdate.isRight()) {
291                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
292                                         result = Either.right(resultUpdate.right().value());
293                                 }
294                         }
295                         if (result == null) {
296                                 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
297                                 result = operation.getToscaElement(toscaElement.getUniqueId());
298                         }
299                         return result;
300
301                 } catch (Exception e) {
302                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
303                 }
304                 return result;
305         }
306
307         /**
308          * Starts certification of tosca element
309          * 
310          * @param toscaElementId
311          * @param modifierId
312          * @param ownerId
313          * @return
314          */
315         public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
316                 Either<ToscaElement, StorageOperationStatus> result = null;
317                 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
318                 GraphVertex toscaElement = null;
319                 GraphVertex modifier = null;
320                 GraphVertex owner;
321                 try {
322                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
323                         if (getVerticesRes.isRight()) {
324                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
325                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
326                         }
327                         if (result == null) {
328                                 toscaElement = getVerticesRes.left().value().get(toscaElementId);
329                                 modifier = getVerticesRes.left().value().get(modifierId);
330                                 owner = getVerticesRes.left().value().get(ownerId);
331
332                                 StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
333                                 if (status != StorageOperationStatus.OK) {
334                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations during certification of tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
335                                 }
336                         }
337                         if (result == null) {
338                                 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
339
340                                 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
341                                 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
342
343                                 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
344                                 if (resultUpdate.isRight()) {
345                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
346                                         result = Either.right(resultUpdate.right().value());
347                                 }
348                         }
349                         if (result == null) {
350                                 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
351                                 result = operation.getToscaElement(toscaElement.getUniqueId());
352                         }
353                 } catch (Exception e) {
354                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
355                 }
356                 return result;
357         }
358
359         public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
360                 Either<ToscaElement, StorageOperationStatus> result = null;
361                 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
362                 GraphVertex toscaElement = null;
363                 GraphVertex modifier = null;
364                 GraphVertex certifiedToscaElement = null;
365                 Integer majorVersion = null;
366
367                 StorageOperationStatus status;
368                 try {
369                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
370                         if (getVerticesRes.isRight()) {
371                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
372                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
373                         }
374                         if (result == null) {
375                                 toscaElement = getVerticesRes.left().value().get(toscaElementId);
376                                 modifier = getVerticesRes.left().value().get(modifierId);
377                                 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
378                                 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
379                                 if (status != StorageOperationStatus.OK) {
380                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
381                                 }
382                         }
383                         if (result == null) {
384                                 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
385                                 if (cloneRes.isRight()) {
386                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
387                                         result = Either.right(cloneRes.right().value());
388                                 }
389                         }
390                         if (result == null) {
391                                 certifiedToscaElement = cloneRes.left().value();
392                                 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
393                                 if (status != StorageOperationStatus.OK) {
394                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
395                                 }
396                         }
397                         if (result == null) {
398                                 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
399                         }
400                 } catch (Exception e) {
401                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
402                 }
403                 return result;
404         }
405
406         /**
407          * Deletes (marks as deleted) all tosca elements according received name and uuid
408          * 
409          * @param vertexType
410          * @param componentType
411          * @param componentName
412          * @param uuid
413          * @return
414          */
415         public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
416
417                 Either<Boolean, StorageOperationStatus> result = null;
418                 ToscaElementOperation operation = getToscaElementOperation(componentType);
419
420                 try {
421                         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
422                         properties.put(GraphPropertyEnum.UUID, uuid);
423                         properties.put(GraphPropertyEnum.NAME, componentName);
424                         Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
425                         if (getToscaElementsRes.isRight()) {
426                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
427                         }
428                         if (result == null) {
429                                 result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
430                         }
431                         if (result == null) {
432                                 result = Either.left(true);
433                         }
434                 } catch (Exception e) {
435                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
436                 }
437                 return result;
438         }
439
440         /**
441          * Performs cancelation or failure of certification for received tosca element
442          * 
443          * @param toscaElementId
444          * @param modifierId
445          * @param ownerId
446          * @param nextState
447          * @return
448          */
449         public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
450                 Either<ToscaElement, StorageOperationStatus> result = null;
451                 StorageOperationStatus status;
452                 ToscaElementOperation operation = null;
453                 GraphVertex toscaElement = null;
454                 GraphVertex modifier = null;
455                 try {
456                         Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
457                         if (getVerticesRes.isRight()) {
458                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
459                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
460                         }
461                         if (result == null) {
462                                 toscaElement = getVerticesRes.left().value().get(toscaElementId);
463                                 modifier = getVerticesRes.left().value().get(modifierId);
464                                 operation = getToscaElementOperation(toscaElement.getLabel());
465                                 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
466                                 toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
467                                 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
468
469                                 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
470                                 if (updateVertexRes.isRight()) {
471                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
472                                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
473                                 }
474                         }
475                         if (result == null) {
476                                 // cancel certification process
477                                 status = handleRelationsUponCancelCertification(toscaElement, nextState);
478                                 if (status != StorageOperationStatus.OK) {
479                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon cancel certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
480                                 }
481                         }
482                         if (result == null) {
483                                 // fail certification
484                                 status = handleRelationsUponFailCertification(toscaElement, nextState);
485                                 if (status != StorageOperationStatus.OK) {
486                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon fail certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
487                                 }
488                         }
489                         if (result == null) {
490                                 result = operation.getToscaElement(toscaElementId);
491                         }
492                 } catch (Exception e) {
493                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during cancel or fail certification of tosca element {}. {}. ", toscaElementId, e.getMessage());
494                 }
495                 return result;
496         }
497
498         public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
499                 return findUserVertex(userId);
500         }
501
502         private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
503                 Either<Boolean, StorageOperationStatus> result = Either.left(true);
504                 for (GraphVertex resourceToDelete : toscaElements) {
505                         if (!((String) resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
506                                 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
507                                 if (deleteElementRes.isRight()) {
508                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
509                                         result = Either.right(deleteElementRes.right().value());
510                                         break;
511                                 }
512                         }
513                 }
514                 return result;
515         }
516
517         private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
518                 StorageOperationStatus result = null;
519                 Edge foundEdge = null;
520                 Iterator<Edge> certReqUserEdgeIter = null;
521                 // add rfc relation to preserve follower information
522                 // get user of certification request
523                 certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
524                 if (certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()) {
525                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
526                         result = StorageOperationStatus.NOT_FOUND;
527                 }
528                 if (result == null) {
529                         TitanOperationStatus createVersionEdgeStatus = titanDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
530                         if (createVersionEdgeStatus != TitanOperationStatus.OK) {
531                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(),certifiedToscaElement.getUniqueId(), createVersionEdgeStatus);
532                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createVersionEdgeStatus);
533                         }
534                 }
535                 if(result == null){
536
537                         while (certReqUserEdgeIter.hasNext()) {
538                                 Edge edge = certReqUserEdgeIter.next();
539                                 if (((String) titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name())) {
540                                         foundEdge = edge;
541                                         break;
542                                 }
543
544                         }
545                         if (foundEdge == null) {
546                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
547                                 result = StorageOperationStatus.NOT_FOUND;
548                         }
549                 }
550                 if (result == null) {
551                         TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
552                         if (createEdgeRes != TitanOperationStatus.OK) {
553                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
554                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
555                         }
556                 }
557                 if (result == null) {
558                         result = StorageOperationStatus.OK;
559                 }
560                 return result;
561         }
562
563         private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
564                 StorageOperationStatus result = null;
565                 TitanOperationStatus status = null;
566                 Edge originEdge;
567                 Vertex user = null;
568                 if (nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) {
569                         // fail certification
570                         // delete relation CERTIFICATION_IN_PROGRESS
571                         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
572                         properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
573
574                         Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
575                         if (deleteResult.isRight()) {
576                                 status = deleteResult.right().value();
577                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
578                                 result = StorageOperationStatus.INCONSISTENCY;
579                         }
580                         if (result == null) {
581                                 // delete relation READY_FOR_CERTIFICATION
582                                 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
583                                 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
584                                 if (deleteResult.isRight()) {
585                                         status = deleteResult.right().value();
586                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
587                                         result = StorageOperationStatus.INCONSISTENCY;
588                                 }
589                         }
590                         if (result == null) {
591                                 // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
592                                 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
593                                 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
594                                 if (deleteResult.isRight()) {
595                                         status = deleteResult.right().value();
596                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
597                                         result = StorageOperationStatus.INCONSISTENCY;
598                                 }
599                         }
600                         if (result == null) {
601                                 // create new STATE relation NOT_CERTIFIED_CHECKIN
602                                 originEdge = deleteResult.left().value();
603                                 user = originEdge.outVertex();
604                                 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
605                                 if (status != TitanOperationStatus.OK) {
606                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
607                                         result = StorageOperationStatus.INCONSISTENCY;
608                                 }
609                         }
610                         if (result == null) {
611                                 // delete relation LAST_MODIFIER (in order to change tester to designer)
612                                 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
613                                 if (status != TitanOperationStatus.OK) {
614                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
615                                         result = StorageOperationStatus.INCONSISTENCY;
616                                 }
617                         }
618                         if (result == null) {
619                                 // create new LAST_MODIFIER relation
620                                 originEdge = deleteResult.left().value();
621                                 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
622                                 if (status != TitanOperationStatus.OK) {
623                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
624                                         result = StorageOperationStatus.INCONSISTENCY;
625                                 }
626                         }
627                 }
628                 if (result == null) {
629                         result = StorageOperationStatus.OK;
630                 }
631                 return result;
632         }
633
634         private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
635                 StorageOperationStatus result = null;
636                 Edge originEdge;
637                 if (nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
638                         // delete relation CERTIFICATION_IN_PROGRESS
639                         Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
640                         properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
641                         Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
642
643                         if (deleteResult.isRight()) {
644                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is  {}. ", deleteResult.right().value());
645                                 result = StorageOperationStatus.INCONSISTENCY;
646                         }
647                         if (result == null) {
648                                 // delete relation READY_FOR_CERTIFICATION (LAST_STATE)
649                                 properties.put(GraphPropertyEnum.STATE, nextState);
650                                 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
651
652                                 if (deleteResult.isRight()) {
653                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", deleteResult.right().value());
654                                         result = StorageOperationStatus.INCONSISTENCY;
655                                 }
656                         }
657                         if (result == null) {
658                                 // create relation READY_FOR_CERTIFICATION (STATE)
659                                 originEdge = deleteResult.left().value();
660                                 TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
661                                 if (status != TitanOperationStatus.OK) {
662                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
663                                         result = StorageOperationStatus.INCONSISTENCY;
664                                 }
665                         }
666                         if (result == null) {
667                                 result = StorageOperationStatus.OK;
668                         }
669                 }
670                 return result;
671         }
672
673         private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
674                 StorageOperationStatus result = null;
675                 if (majorVersion > 0) {
676                         Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
677                         if (findRes.isRight()) {
678                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
679                                 result = findRes.right().value();
680                         }
681                         if (result == null) {
682                                 Vertex lastCertifiedVertex = findRes.left().value();
683                                 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
684                                 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
685                                 TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
686                                 if (status != TitanOperationStatus.OK) {
687                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set highest version  of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
688                                         result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
689                                 }
690                         }
691                 }
692                 if (result == null) {
693                         result = StorageOperationStatus.OK;
694                 }
695                 return result;
696         }
697
698         private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
699                 TitanOperationStatus status;
700                 StorageOperationStatus result = null;
701
702                 if (((String) toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
703                         // remove CHECKOUT relation
704                         Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
705                         if (deleteRes.isRight()) {
706                                 status = deleteRes.right().value();
707                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
708                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
709                         }
710                         if (result == null) {
711                                 // create CHECKIN relation
712                                 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
713                                 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
714                                 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
715                                 if (status != TitanOperationStatus.OK) {
716                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
717                                         result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
718                                 }
719                         }
720                 } else {
721                         status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
722                         if (status != TitanOperationStatus.OK) {
723                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
724                         }
725                 }
726                 if (result == null) {
727                         // create RFC relation
728                         Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
729                         properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
730                         status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
731                         if (status != TitanOperationStatus.OK) {
732                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
733                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
734                         }
735                 }
736                 if (result == null) {
737                         result = StorageOperationStatus.OK;
738                 }
739                 return result;
740         }
741
742         private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
743
744                 StorageOperationStatus result = null;
745                 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
746                 if (status != TitanOperationStatus.OK) {
747                         result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
748                 }
749                 if (result == null) {
750                         Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
751                         properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
752                         status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
753                         if (status != TitanOperationStatus.OK) {
754                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
755                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
756                         }
757                 }
758                 if (result == null) {
759                         result = StorageOperationStatus.OK;
760                 }
761                 return result;
762         }
763
764         private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
765                 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
766         }
767
768         private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
769                 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
770                         return Either.left(vertex);
771                 }
772                 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
773                 if (!edgeIter.hasNext()) {
774                         return Either.right(StorageOperationStatus.NOT_FOUND);
775                 }
776                 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
777         }
778
779         private boolean isCertifiedVersion(String version) {
780                 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
781                 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
782                         return true;
783                 }
784                 return false;
785         }
786
787         private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
788
789                 StorageOperationStatus result = StorageOperationStatus.OK;
790                 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
791                 if (!previousVersion.endsWith(".0")) {
792                         try {
793                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
794
795                                 Map<String, Object> propertiesToUpdate = new HashMap<>();
796                                 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
797                                 Map<String, Object> jsonMetadataMap = JsonParserUtils.parseToJson((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
798                                 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
799                                 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.jsonToString(jsonMetadataMap));
800
801                                 titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
802
803                                 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
804                                 if (!edgesIter.hasNext()) {
805                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
806                                         result = StorageOperationStatus.NOT_FOUND;
807                                 } else {
808                                         Edge lastStateEdge = edgesIter.next();
809                                         Vertex lastModifier = lastStateEdge.outVertex();
810                                         TitanOperationStatus replaceRes = titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
811                                         if (replaceRes != TitanOperationStatus.OK) {
812                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
813                                                 result = StorageOperationStatus.INCONSISTENCY;
814                                                 if (replaceRes != TitanOperationStatus.INVALID_ID) {
815                                                         result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
816                                                 }
817                                         }
818                                 }
819                         } catch (Exception e) {
820                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
821                         }
822                 }
823                 return result;
824         }
825
826         private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
827                 StorageOperationStatus result = null;
828                 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
829                 String toscaElementId = toscaElementVertex.getUniqueId();
830                 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
831                         toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
832                         Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
833                         if (updateVertexRes.isRight()) {
834                                 TitanOperationStatus titatStatus = updateVertexRes.right().value();
835                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
836                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
837                         }
838                         Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
839                         if (result == null) {
840                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
841
842                                 deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
843                                 if (deleteEdgeRes.isRight()) {
844                                         TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
845                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
846                                         if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
847                                                 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
848                                         } else {
849                                                 result = StorageOperationStatus.INCONSISTENCY;
850                                         }
851                                 }
852                         }
853                         if (result == null) {
854                                 TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
855                                 if (createEdgeRes != TitanOperationStatus.OK) {
856                                         result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
857                                 }
858                         }
859                 }
860                 if (result == null) {
861                         result = StorageOperationStatus.OK;
862                 }
863                 return result;
864         }
865
866         private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
867
868                 Either<ToscaElement, StorageOperationStatus> result = null;
869                 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
870                 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
871                 // check if component with the next version doesn't exist.
872                 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
873                 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
874                         String fetchedVersion = (String) nextVersionComponentIter.next().inVertex().property(GraphPropertyEnum.VERSION.getProperty()).value();
875                         String fetchedName = (String) nextVersionComponentIter.next().inVertex().property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
876                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
877                                         toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
878                         result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
879                 }
880                 if (result == null) {
881                         cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
882                         if (cloneResult.isRight()) {
883                                 result = Either.right(cloneResult.right().value());
884                         }
885                 }
886                 GraphVertex clonedVertex = null;
887                 if (result == null) {
888                         clonedVertex = cloneResult.left().value();
889                         TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
890                         if (status != TitanOperationStatus.OK) {
891                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
892                                                 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
893                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
894                         }
895                 }
896                 if (result == null) {
897                         result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
898                         if (result.isRight()) {
899                                 return result;
900                         }
901
902                         ToscaElement toscaElement = result.left().value();
903                         if (toscaElement.getToscaType() == ToscaElementTypeEnum.TopologyTemplate) {
904                                 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
905                         }
906                 }
907                 return result;
908         }
909
910         private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
911                         ToscaElement toscaElement) {
912                 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
913                 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
914                 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
915                 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
916                 Map<String, ToscaElement> origCompMap = new HashMap<>();
917                 if (instInputs == null) {
918                         instInputs = new HashMap<>();
919                 }
920                 if (instGroups == null) {
921                         instGroups = new HashMap<>();
922                 }
923                 if (instArtifactsMap == null) {
924                         instArtifactsMap = new HashMap<>();
925                 }
926                 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
927                 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
928                 boolean needUpdateComposition = false;
929
930                 if (instancesMap != null && !instancesMap.isEmpty()) {
931                         for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
932                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
933                                 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
934                                         collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
935                                 }
936                                 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
937                                 if(needUpdateComposition){
938                                         instancesMap.put(vfInst.getUniqueId(), vfInst);
939                                 }
940                         }
941                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add to graph instInputs {}  instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
942                         if (!instInputs.isEmpty()) {
943                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
944                                 GraphVertex toscaDataVertex = null;
945                                 Either<GraphVertex, TitanOperationStatus> instInpVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
946                                 if (instInpVertexEither.isLeft()) {
947                                         toscaDataVertex = instInpVertexEither.left().value();
948                                 }
949
950                                 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
951                                 if (status != StorageOperationStatus.OK) {
952                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
953                                         result = Either.right(status);
954                                         return result;
955                                 }
956
957                         }
958                         if (!instGroups.isEmpty()) {
959                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
960                                 GraphVertex toscaDataVertex = null;
961                                 Either<GraphVertex, TitanOperationStatus> instGrVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
962                                 if (instGrVertexEither.isLeft()) {
963                                         toscaDataVertex = instGrVertexEither.left().value();
964                                 }
965
966                                 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
967                                 if (status != StorageOperationStatus.OK) {
968                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
969                                         result = Either.right(status);
970                                         return result;
971                                 }
972
973                         }
974                         if (needUpdateComposition) {
975                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before update Instances ");
976                                 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
977                                 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
978                                 compositionDataDefinition.setComponentInstances(instancesMap);
979                                 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(clonedVertex);
980                                 if (updateElement.isRight()) {
981                                         TitanOperationStatus status = updateElement.right().value();
982                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
983                                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
984                                         return result;
985                                 }
986                         }
987
988                         result = operation.getToscaElement(clonedVertex.getUniqueId());
989
990                 } else {
991                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
992                 }
993                 return result;
994         }
995         
996         //TODO remove after jsonModelMigration
997         public void resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
998                 fixToscaComponentName(vfInst, origCompMap);
999         }
1000
1001         private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
1002                 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
1003                         String ciUid = vfInst.getUniqueId();
1004                         String origCompUid = vfInst.getComponentUid();
1005                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
1006                         ToscaElement origComp = null;
1007                         if (!origCompMap.containsKey(origCompUid)) {
1008                                 Either<ToscaElement, StorageOperationStatus> origCompEither;
1009                                 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
1010                                         origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1011                                 }else{
1012                                         origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
1013                                 }
1014                                 if (origCompEither.isRight()) {
1015                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1016                                         return false;
1017                                 }
1018                                 origComp =  origCompEither.left().value();
1019                                 origCompMap.put(origCompUid, origComp);
1020                         } else {
1021                                 origComp = origCompMap.get(origCompUid);
1022                         }
1023                         String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
1024                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
1025                         vfInst.setToscaComponentName(toscaName);
1026                         return true;
1027                 }
1028                 return false;
1029         }
1030
1031         private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
1032                         boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
1033                 String ciUid = vfInst.getUniqueId();
1034                 String origCompUid = vfInst.getComponentUid();
1035                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
1036                 TopologyTemplate origComp = null;
1037                 if (!origCompMap.containsKey(origCompUid)) {
1038                         Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1039                         if (origCompEither.isRight()) {
1040                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1041                                 return;
1042                         }
1043                         origComp = (TopologyTemplate) origCompEither.left().value();
1044                         origCompMap.put(origCompUid, origComp);
1045                 } else {
1046                         origComp = (TopologyTemplate) origCompMap.get(origCompUid);
1047                 }
1048                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
1049
1050                 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
1051                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
1052                 if (origInputs != null) {
1053                         if (!instInputs.containsKey(ciUid)) {
1054                                 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
1055                                 instInputs.put(ciUid, instProperties);
1056                         } else {
1057
1058                                 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
1059                                 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
1060                                 origInputs.forEach((propName, propMap) -> {
1061                                         if (!instProp.containsKey(propName)) {
1062                                                 instProp.put(propName, propMap);
1063                                         }
1064                                 });
1065                         }
1066                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
1067                 }
1068
1069                 if (isAddInstGroup) {
1070                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before create group instance. ");
1071                         List<GroupDataDefinition> filteredGroups = null;
1072
1073                         
1074                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1075                         if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
1076                                 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
1077                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1078                         }
1079                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1080                         if (CollectionUtils.isNotEmpty(filteredGroups)) {
1081                                 MapArtifactDataDefinition instArifacts = null;
1082                                 if(!instArtifactsMap.containsKey(ciUid)){
1083                                 
1084                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "istance artifacts not found ");
1085                                                 
1086                                                 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
1087                                                 
1088                                                 
1089                                                 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
1090                                                  addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
1091                                                 
1092                                                  instArtifactsMap.put(ciUid, instArifacts);
1093                                                 
1094                                 }else{
1095                                         instArifacts = instArtifactsMap.get(ciUid);
1096                                 }
1097                                         
1098                                 if(instArifacts != null){
1099                                         Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
1100                                 
1101                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
1102                                         Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
1103                                         for(GroupDataDefinition group:filteredGroups){
1104                                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance  {} ", group.getName());
1105                                                 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst);
1106                                                 List<String> artifactsUid = new ArrayList<>();
1107                                                 List<String> artifactsId = new ArrayList<>();
1108                                                 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
1109                                                         //CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance  {} ", artifact.getA);
1110                                                         Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
1111                                                         if (op.isPresent()) {
1112                                                                 artifactsUid.add(artifact.getArtifactUUID());
1113                                                                 artifactsId.add(artifact.getUniqueId());
1114                                                                 
1115                                                         }
1116                                                 }
1117                                                 groupInstance.setGroupInstanceArtifacts(artifactsId);
1118                                                 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
1119                                                 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
1120                                         }
1121                                         if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
1122                                                 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
1123         
1124                                         }
1125                                 }
1126                         }
1127                 }
1128         }
1129
1130         private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
1131                 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1132                 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
1133                 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1134                 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1135                 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1136                 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1137                 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1138
1139                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1140                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1141                 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
1142                 if (isFirstCheckoutAfterCertification(nextVersion)) {
1143                         nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
1144                 }
1145                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
1146                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
1147                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1148
1149                 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
1150                         nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
1151                 }
1152                 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1153                         nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
1154                         nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1155                 }
1156                 long currTime = System.currentTimeMillis();
1157                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
1158                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
1159                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1160                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1161                 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
1162                         nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
1163                 }
1164
1165                 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1166                         nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1167                 }
1168                 return nextVersionToscaElementVertex;
1169         }
1170
1171         private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1172                 Either<GraphVertex, StorageOperationStatus> result;
1173                 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
1174                 GraphVertex clonedToscaElement = null;
1175                 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
1176                 if (result.isRight()) {
1177                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
1178                 } else {
1179                         clonedToscaElement = result.left().value();
1180                         deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
1181                         if (deleteResult.isRight()) {
1182                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
1183                                 result = Either.right(deleteResult.right().value());
1184                         }
1185                 }
1186                 if (result.isLeft()) {
1187                         result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
1188                 }
1189                 return result;
1190         }
1191
1192         private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
1193                 Either<GraphVertex, StorageOperationStatus> result = null;
1194                 Vertex previousCertifiedToscaElement = null;
1195                 if (majorVersion > 0) {
1196                         List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
1197
1198                         if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
1199                                 result = Either.right(StorageOperationStatus.NOT_FOUND);
1200                         } else {
1201                                 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
1202                                 if (previousCertifiedToscaElement == null) {
1203                                         result = Either.right(StorageOperationStatus.NOT_FOUND);
1204                                 }
1205                         }
1206                         if (result == null) {
1207                                 TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
1208                                 if (status != TitanOperationStatus.OK) {
1209                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
1210                                                         previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
1211                                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
1212                                 }
1213                         }
1214                 }
1215                 if (result == null) {
1216                         result = Either.left(clonedToscaElement);
1217                 }
1218                 return result;
1219         }
1220
1221         private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
1222
1223                 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
1224                 if (edges.hasNext()) {
1225                         return edges.next().outVertex();
1226                 }
1227                 return null;
1228         }
1229
1230         private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
1231                 Either<List<GraphVertex>, StorageOperationStatus> result = null;
1232
1233                 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
1234                 List<GraphVertex> previosVersions = null;
1235                 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
1236                 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
1237                 try {
1238                         Map<GraphPropertyEnum, Object> properties = new HashMap<>();
1239                         properties.put(GraphPropertyEnum.UUID, uuid);
1240                         properties.put(GraphPropertyEnum.NAME, componentName);
1241                         Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
1242                         if (getToscaElementsRes.isRight()) {
1243                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
1244                         }
1245                         if (result == null) {
1246                                 previosVersions = getToscaElementsRes.left().value();
1247                                 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
1248                                 if (deleteResult.isRight()) {
1249                                         result = Either.right(deleteResult.right().value());
1250                                 }
1251                         }
1252                         if (result == null) {
1253                                 result = Either.left(previosVersions);
1254                         }
1255                 } catch (Exception e) {
1256                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
1257                 }
1258                 return result;
1259         }
1260
1261         private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1262
1263                 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1264                 String uniqueId = IdBuilderUtils.generateUniqueId();
1265                 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1266                 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1267                 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1268                 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1269                 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1270
1271                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1272                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1273                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMETER + "0");
1274                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1275                 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1276                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
1277                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
1278                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1279                 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1280
1281                 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
1282                         nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
1283                 }
1284                 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1285                         nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
1286                         nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1287                 }
1288                 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1289                         nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1290                 }
1291                 return nextVersionToscaElementVertex;
1292         }
1293
1294         private ComponentParametersView buildComponentParametersViewAfterCheckin() {
1295                 ComponentParametersView componentParametersView = new ComponentParametersView();
1296                 componentParametersView.disableAll();
1297                 componentParametersView.setIgnoreUsers(false);
1298                 return componentParametersView;
1299         }
1300
1301         private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
1302                 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
1303                 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
1304                 if (result.isLeft()) {
1305                         toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
1306                         toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1307                         result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
1308                 }
1309                 if (result.isLeft()) {
1310                         updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
1311                         if (updateRelationsRes.isRight()) {
1312                                 result = Either.right(updateRelationsRes.right().value());
1313                         }
1314                 }
1315                 return result;
1316         }
1317
1318         private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
1319
1320                 Either<GraphVertex, StorageOperationStatus> result;
1321
1322                 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
1323                 if (updateVertexRes.isRight()) {
1324                         TitanOperationStatus titatStatus = updateVertexRes.right().value();
1325                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is  {}", toscaElementVertex.getUniqueId(), titatStatus);
1326                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
1327                 } else {
1328                         result = Either.left(updateVertexRes.left().value());
1329                 }
1330                 return result;
1331         }
1332
1333         private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1334                 Either<GraphVertex, StorageOperationStatus> result = null;
1335                 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
1336                 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is  {}";
1337
1338                 if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
1339                         // In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
1340                         Map<GraphPropertyEnum, Object> vertexProperties = new HashMap<>();
1341                         vertexProperties.put(GraphPropertyEnum.STATE, nextState);
1342                         Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
1343                         if (deleteResult.isRight()) {
1344                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
1345                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to update last state relation");
1346                                 result = Either.right(StorageOperationStatus.INCONSISTENCY);
1347                         }
1348                 }
1349                 if (result == null) {
1350                         // Remove CHECKOUT relation
1351                         Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
1352                         if (deleteEdgeResult.isRight()) {
1353                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1354                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
1355                         }
1356                 }
1357                 if (result == null) {
1358                         // Create CHECKIN relation
1359                         Map<EdgePropertyEnum, Object> edgeProperties = new HashMap<>();
1360                         edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1361                         TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1362                         if (createEdgeRes != TitanOperationStatus.OK) {
1363                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1364                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1365                         }
1366                 }
1367                 if (result == null) {
1368                         result = Either.left(toscaElementVertex);
1369                 }
1370                 return result;
1371         }
1372
1373         private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1374                 Either<GraphVertex, StorageOperationStatus> result = null;
1375                 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
1376                         Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1377                         if (deleteEdgeRes.isRight()) {
1378                                 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1379                                 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
1380                         }
1381                         if (result == null) {
1382                                 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1383
1384                                 if (createEdgeRes != TitanOperationStatus.OK) {
1385                                         CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1386                                         result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1387                                 } else {
1388                                         result = Either.left(modifierVertex);
1389                                 }
1390                         }
1391                 } else {
1392                         result = Either.left(ownerVertex);
1393                 }
1394                 return result;
1395         }
1396
1397         private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1398                 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1399                 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1400                 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1401                 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1402                 return verticesToGetParameters;
1403         }
1404
1405         private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1406                 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1407                 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1408                 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1409                 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1410                 return verticesToGetParameters;
1411         }
1412
1413         private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1414                 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1415                 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1416                 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1417                 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1418                 return verticesToGetParameters;
1419         }
1420
1421         private String getNextVersion(String currVersion) {
1422                 String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP);
1423                 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1424                 return versionParts[0] + VERSION_DELIMETER + minorVersion;
1425         }
1426
1427         private Integer getMinorVersion(String version) {
1428                 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1429                 return Integer.parseInt(versionParts[1]);
1430         }
1431
1432         private Integer getMajorVersion(String version) {
1433                 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1434                 return Integer.parseInt(versionParts[0]);
1435         }
1436
1437         private boolean isFirstCheckoutAfterCertification(String version) {
1438                 if (Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[1]) == 1) {
1439                         return true;
1440                 }
1441                 return false;
1442         }
1443 }