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