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