1 package org.openecomp.sdc.be.model.jsontitan.operations;
3 import java.util.EnumMap;
4 import java.util.HashMap;
5 import java.util.Iterator;
8 import java.util.stream.Collectors;
10 import org.apache.commons.collections.CollectionUtils;
11 import org.apache.commons.collections.MapUtils;
12 import org.apache.commons.lang.StringUtils;
13 import org.apache.commons.lang3.tuple.ImmutablePair;
14 import org.apache.tinkerpop.gremlin.structure.Direction;
15 import org.apache.tinkerpop.gremlin.structure.Edge;
16 import org.apache.tinkerpop.gremlin.structure.Vertex;
17 import org.openecomp.sdc.be.config.ConfigurationManager;
18 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
19 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
20 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
21 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
22 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
23 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
24 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
25 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
26 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
27 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
28 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
29 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
30 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
31 import org.openecomp.sdc.be.model.ComponentParametersView;
32 import org.openecomp.sdc.be.model.DistributionStatusEnum;
33 import org.openecomp.sdc.be.model.LifecycleStateEnum;
34 import org.openecomp.sdc.be.model.User;
35 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
36 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
37 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
38 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
39 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
40 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
44 import fj.data.Either;
46 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
49 * Allows to perform lifecycle operations:
50 * checkin, checkout, submit for testing, start certification and certification process
53 public class ToscaElementLifecycleOperation extends BaseOperation {
55 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
56 public static final String VERSION_DELIMETER = ".";
57 public static final String VERSION_DELIMETER_REGEXP = "\\.";
59 private static Logger logger = LoggerFactory.getLogger(ToscaElementLifecycleOperation.class.getName());
62 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
64 * @param toscaElementId
69 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
70 Either<GraphVertex, StorageOperationStatus> updateResult = null;
71 Either<ToscaElement, StorageOperationStatus> result = null;
72 Map<String, GraphVertex> vertices = null;
73 ToscaElementOperation operation;
75 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
76 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
77 if(getVerticesRes.isRight()){
78 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
79 updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
81 vertices = getVerticesRes.left().value();
82 updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
84 if(updateResult.isLeft()) {
85 ComponentParametersView componentParametersView = buildComponentParametersViewAfterCheckin();
86 operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
87 result = operation.getToscaElement(updateResult.left().value().getUniqueId(), componentParametersView);
89 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
92 result = Either.right(updateResult.right().value());
94 } catch (Exception e){
95 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
100 * Returns vertex presenting owner of tosca element specified by uniqueId
101 * @param toscaElement
104 public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
105 Either<User, StorageOperationStatus> result = null;
106 GraphVertex toscaElement = null;
107 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
108 if(getToscaElementRes.isRight()){
109 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
112 toscaElement = getToscaElementRes.left().value();
113 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
114 if(vertices == null || !vertices.hasNext()){
115 result = Either.right(StorageOperationStatus.NOT_FOUND);
117 result = Either.left(convertToUser(vertices.next()));
123 * Returns vertex presenting owner of tosca element specified by uniqueId
124 * @param toscaElement
127 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
128 Either<User, StorageOperationStatus> result = null;
129 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
130 if(vertices == null || !vertices.hasNext()){
131 result = Either.right(StorageOperationStatus.NOT_FOUND);
133 result = Either.left(convertToUser(vertices.next()));
139 * Performs checkout of a tosca element
140 * @param toscaElementId
146 public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
147 Either<ToscaElement, StorageOperationStatus> result = null;
148 Map<String, GraphVertex> vertices = null;
150 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
151 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
152 if(getVerticesRes.isRight()){
153 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
154 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
157 vertices = getVerticesRes.left().value();
158 // update previous component if not certified
159 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
160 if(status != StorageOperationStatus.OK){
161 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
162 result = Either.right(status);
166 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
167 if (result.isRight()) {
168 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
171 } catch (Exception e){
172 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
177 * Performs undo checkout for tosca element
178 * @param toscaElementId
181 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
182 Either<ToscaElement, StorageOperationStatus> result = null;
183 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
184 Iterator<Edge> nextVersionComponentIter = null;
185 ToscaElementOperation operation;
187 getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
188 if(getToscaElementRes.isRight()){
189 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
190 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
192 if(result == null && hasPreviousVersion(getToscaElementRes.left().value())){
193 // find previous version
194 nextVersionComponentIter = getToscaElementRes.left().value().getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
195 if(nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()){
196 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ",
197 getToscaElementRes.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
198 result = Either.right(StorageOperationStatus.NOT_FOUND);
201 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(nextVersionComponentIter.next().outVertex());
202 if (updateOldResourceResult != StorageOperationStatus.OK) {
203 result = Either.right(updateOldResourceResult);
208 operation = getToscaElementOperation(getToscaElementRes.left().value().getLabel());
209 result = operation.deleteToscaElement(getToscaElementRes.left().value());
211 } catch(Exception e){
212 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
217 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
218 boolean hasPreviousVersion = true;
219 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
220 if(StringUtils.isEmpty(version) || version.equals("0.1"))
221 hasPreviousVersion = false;
222 return hasPreviousVersion;
225 * Performs request certification for tosca element
226 * @param toscaElementId
231 public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
232 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
233 Either<ToscaElement, StorageOperationStatus> result = null;
234 GraphVertex toscaElement = null;
235 GraphVertex modifier = null;
238 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
239 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
240 if(getVerticesRes.isRight()){
241 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
242 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
245 toscaElement = getVerticesRes.left().value().get(toscaElementId);
246 modifier = getVerticesRes.left().value().get(modifierId);
247 owner = getVerticesRes.left().value().get(ownerId);
249 StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
250 if(status != StorageOperationStatus.OK){
251 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations on certification request for tosca element {}. Status is {}. ",
252 toscaElement.getUniqueId(), status);
256 LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
258 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
259 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
261 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
262 if (resultUpdate.isRight()) {
263 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
264 result = Either.right(resultUpdate.right().value());
268 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
269 result = operation.getToscaElement(toscaElement.getUniqueId());
273 } catch (Exception e){
274 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
280 * Starts certification of tosca element
281 * @param toscaElementId
286 public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
287 Either<ToscaElement, StorageOperationStatus> result = null;
288 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
289 GraphVertex toscaElement = null;
290 GraphVertex modifier = null;
293 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
294 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
295 if(getVerticesRes.isRight()){
296 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
297 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
300 toscaElement = getVerticesRes.left().value().get(toscaElementId);
301 modifier = getVerticesRes.left().value().get(modifierId);
302 owner = getVerticesRes.left().value().get(ownerId);
304 StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
305 if(status != StorageOperationStatus.OK){
306 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations during certification of tosca element {}. Status is {}. ",
307 toscaElement.getUniqueId(), status);
311 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
313 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
314 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
316 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
317 if (resultUpdate.isRight()) {
318 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
319 result = Either.right(resultUpdate.right().value());
323 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
324 result = operation.getToscaElement(toscaElement.getUniqueId());
326 } catch (Exception e){
327 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
332 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
333 Either<ToscaElement, StorageOperationStatus> result = null;
334 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
335 GraphVertex toscaElement = null;
336 GraphVertex modifier = null;
337 GraphVertex certifiedToscaElement = null;
338 Integer majorVersion = null;
340 StorageOperationStatus status;
342 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
343 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
344 if(getVerticesRes.isRight()){
345 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
346 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
349 toscaElement = getVerticesRes.left().value().get(toscaElementId);
350 modifier = getVerticesRes.left().value().get(modifierId);
351 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
352 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
353 if(status != StorageOperationStatus.OK){
354 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations of previous tosca element before certifying {}. Status is {}. ",
355 toscaElement.getUniqueId(), status);
359 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
360 if (cloneRes.isRight()) {
361 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
362 result = Either.right(cloneRes.right().value());
366 certifiedToscaElement = cloneRes.left().value();
367 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
368 if(status != StorageOperationStatus.OK){
369 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations of newest certified tosca element {}. Status is {}. ",
370 certifiedToscaElement.getUniqueId(), status);
374 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
376 } catch (Exception e){
377 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
382 * Deletes (marks as deleted) all tosca elements according received name and uuid
384 * @param componentType
385 * @param componentName
389 public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
391 Either<Boolean, StorageOperationStatus> result = null;
392 ToscaElementOperation operation = getToscaElementOperation(componentType);
395 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
396 properties.put(GraphPropertyEnum.UUID, uuid);
397 properties.put(GraphPropertyEnum.NAME, componentName);
398 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes= titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
399 if (getToscaElementsRes.isRight()) {
400 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
403 result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
406 result = Either.left(true);
408 } catch (Exception e){
409 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
414 * Performs cancelation or failure of certification for received tosca element
415 * @param toscaElementId
421 public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
422 Either<ToscaElement, StorageOperationStatus> result = null;
423 StorageOperationStatus status;
424 ToscaElementOperation operation = null;
425 GraphVertex toscaElement = null;
426 GraphVertex modifier = null;
428 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes =
429 titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
430 if(getVerticesRes.isRight()){
431 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
432 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
435 toscaElement = getVerticesRes.left().value().get(toscaElementId);
436 modifier = getVerticesRes.left().value().get(modifierId);
437 operation = getToscaElementOperation(toscaElement.getLabel());
438 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
439 toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
440 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
442 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
443 if(updateVertexRes.isRight()){
444 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
445 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
449 // cancel certification process
450 status = handleRelationsUponCancelCertification(toscaElement, nextState);
451 if(status != StorageOperationStatus.OK){
452 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations upon cancel certification {}. Status is {}. ",
453 toscaElement.getUniqueId(), status);
457 // fail certification
458 status = handleRelationsUponFailCertification(toscaElement, nextState);
459 if(status != StorageOperationStatus.OK){
460 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to handle relations upon fail certification {}. Status is {}. ",
461 toscaElement.getUniqueId(), status);
464 if (result == null) {
465 result = operation.getToscaElement(toscaElementId);
467 } catch (Exception e){
468 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during cancel or fail certification of tosca element {}. {}. ",
469 toscaElementId, e.getMessage());
474 public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
475 return findUserVertex(userId);
478 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
479 Either<Boolean, StorageOperationStatus> result = Either.left(true);
480 for (GraphVertex resourceToDelete : toscaElements) {
481 if(!((String)resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())){
482 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
483 if (deleteElementRes.isRight()) {
484 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
485 result = Either.right(deleteElementRes.right().value());
494 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
495 StorageOperationStatus result = null;
496 Edge foundEdge = null;
497 Iterator<Edge> certReqUserEdgeIter = null;
498 // add rfc relation to preserve follower information
499 // get user of certification request
500 certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
501 if(certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()){
502 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
503 result = StorageOperationStatus.NOT_FOUND;
507 while(certReqUserEdgeIter.hasNext()){
508 Edge edge = certReqUserEdgeIter.next();
509 if(((String)titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name()) ){
515 if(foundEdge == null){
516 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
517 result = StorageOperationStatus.NOT_FOUND;
521 TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
522 if (createEdgeRes != TitanOperationStatus.OK) {
523 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
524 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
528 result = StorageOperationStatus.OK;
533 private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
534 StorageOperationStatus result = null;
535 TitanOperationStatus status = null;
538 if(nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN){
539 // fail certification
540 // delete relation CERTIFICATION_IN_PROGRESS
541 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
542 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
544 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
545 if (deleteResult.isRight()) {
546 status = deleteResult.right().value();
547 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
548 result = StorageOperationStatus.INCONSISTENCY;
551 // delete relation READY_FOR_CERTIFICATION
552 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
553 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
554 if(deleteResult.isRight()){
555 status = deleteResult.right().value();
556 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
557 result = StorageOperationStatus.INCONSISTENCY;
561 // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
562 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
563 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
564 if(deleteResult.isRight()){
565 status = deleteResult.right().value();
566 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
567 result = StorageOperationStatus.INCONSISTENCY;
571 // create new STATE relation NOT_CERTIFIED_CHECKIN
572 originEdge = deleteResult.left().value();
573 user = originEdge.outVertex();
574 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
575 if (status != TitanOperationStatus.OK) {
576 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
577 result = StorageOperationStatus.INCONSISTENCY;
581 // delete relation LAST_MODIFIER (in order to change tester to designer)
582 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
583 if (status != TitanOperationStatus.OK) {
584 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
585 result = StorageOperationStatus.INCONSISTENCY;
589 // create new LAST_MODIFIER relation
590 originEdge = deleteResult.left().value();
591 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
592 if (status != TitanOperationStatus.OK) {
593 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
594 result = StorageOperationStatus.INCONSISTENCY;
599 result = StorageOperationStatus.OK;
604 private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
605 StorageOperationStatus result = null;
607 if(nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION){
608 // delete relation CERTIFICATION_IN_PROGRESS
609 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
610 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
611 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
613 if (deleteResult.isRight()) {
614 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", deleteResult.right().value());
615 result = StorageOperationStatus.INCONSISTENCY;
618 // delete relation READY_FOR_CERTIFICATION (LAST_STATE)
619 properties.put(GraphPropertyEnum.STATE, nextState);
620 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
622 if (deleteResult.isRight()) {
623 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", deleteResult.right().value());
624 result = StorageOperationStatus.INCONSISTENCY;
628 // create relation READY_FOR_CERTIFICATION (STATE)
629 originEdge = deleteResult.left().value();
630 TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
631 if (status != TitanOperationStatus.OK) {
632 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
633 result = StorageOperationStatus.INCONSISTENCY;
637 result = StorageOperationStatus.OK;
643 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
644 StorageOperationStatus result = null;
645 if (majorVersion > 0) {
646 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
647 if(findRes.isRight()){
648 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
649 result = findRes.right().value();
652 Vertex lastCertifiedVertex = findRes.left().value();
653 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
654 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
655 TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
656 if (status != TitanOperationStatus.OK) {
657 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to set highest version of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
658 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
663 result = StorageOperationStatus.OK;
668 private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
669 TitanOperationStatus status;
670 StorageOperationStatus result = null;
672 if (((String)toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
673 // remove CHECKOUT relation
674 Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
675 if (deleteRes.isRight()) {
676 status = deleteRes.right().value();
677 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
678 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
681 // create CHECKIN relation
682 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
683 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
684 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
685 if (status != TitanOperationStatus.OK) {
686 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
687 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
691 status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
692 if (status != TitanOperationStatus.OK) {
693 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
697 // create RFC relation
698 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
699 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
700 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
701 if (status != TitanOperationStatus.OK) {
702 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
703 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
707 result = StorageOperationStatus.OK;
712 private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
714 StorageOperationStatus result = null;
715 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
716 if (status != TitanOperationStatus.OK) {
717 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
720 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
721 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
722 status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
723 if (status != TitanOperationStatus.OK) {
724 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"failed to create edge. Status is {}", status);
725 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
729 result = StorageOperationStatus.OK;
734 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
735 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
738 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
739 if(isCertifiedVersion((String)vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())){
740 return Either.left(vertex);
742 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
743 if(!edgeIter.hasNext()){
744 return Either.right(StorageOperationStatus.NOT_FOUND);
746 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
749 private boolean isCertifiedVersion(String version) {
750 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
751 if(Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0){
757 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
759 StorageOperationStatus result = StorageOperationStatus.OK;
760 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
761 if (!previousVersion.endsWith(".0")) {
763 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element",
764 previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
766 Map<String, Object> propertiesToUpdate = new HashMap<>();
767 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
768 Map<String, Object> jsonMetadataMap =
769 JsonParserUtils.parseToJson((String)previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
770 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
771 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.jsonToString(jsonMetadataMap));
773 titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
775 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
776 if(!edgesIter.hasNext()){
777 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
778 result = StorageOperationStatus.NOT_FOUND;
780 Edge lastStateEdge = edgesIter.next();
781 Vertex lastModifier = lastStateEdge.outVertex();
782 TitanOperationStatus replaceRes =
783 titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
784 if (replaceRes != TitanOperationStatus.OK) {
785 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
786 result = StorageOperationStatus.INCONSISTENCY;
787 if (replaceRes != TitanOperationStatus.INVALID_ID) {
788 result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
792 } catch (Exception e){
793 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
798 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
799 StorageOperationStatus result = null;
800 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
801 String toscaElementId = toscaElementVertex.getUniqueId();
802 if(!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())){
803 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
804 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
805 if (updateVertexRes.isRight()) {
806 TitanOperationStatus titatStatus = updateVertexRes.right().value();
807 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
808 "Failed to update tosca element vertex {}. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
809 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
811 Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
813 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE,"Going to replace edge with label {} to label {} from {} to {}. ",
814 EdgeLabelEnum.STATE , EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
816 deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
817 if(deleteEdgeRes.isRight()){
818 TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
819 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,
820 "Failed to delete edge with label {} from {} to {}. Status is {} ",
821 EdgeLabelEnum.STATE , EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
822 if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
823 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
825 result = StorageOperationStatus.INCONSISTENCY;
830 TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
831 if(createEdgeRes != TitanOperationStatus.OK){
832 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
837 result = StorageOperationStatus.OK;
842 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
844 Either<ToscaElement, StorageOperationStatus> result = null;
845 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
846 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
847 // check if component with the next version doesn't exist.
848 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
849 if(nextVersionComponentIter != null && nextVersionComponentIter.hasNext()){
850 String fetchedVersion = (String) nextVersionComponentIter.next().inVertex().property(GraphPropertyEnum.VERSION.getProperty()).value();
851 String fetchedName = (String) nextVersionComponentIter.next().inVertex().property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
852 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. ",
853 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
854 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
857 cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
858 if(cloneResult.isRight()){
859 result = Either.right(cloneResult.right().value());
862 if (result == null) {
863 TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
864 if (status != TitanOperationStatus.OK) {
865 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION, toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
866 cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
867 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
871 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
876 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
877 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
878 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
879 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
880 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
881 nextVersionToscaElementVertex.setUniqueId(uniqueId);
882 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
883 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
885 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
886 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
887 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
888 if(isFirstCheckoutAfterCertification(nextVersion)){
889 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
891 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
892 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
893 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
895 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
896 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
898 if(!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())){
899 nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
900 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
902 long currTime = System.currentTimeMillis();
903 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
904 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
905 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
906 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
907 if(toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
908 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
911 if(!MapUtils.isEmpty(toscaElementVertex.getJson())){
912 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
914 return nextVersionToscaElementVertex;
917 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
918 Either<GraphVertex, StorageOperationStatus> result;
919 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
920 GraphVertex clonedToscaElement = null;
921 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
922 if(result.isRight()){
923 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
926 clonedToscaElement = result.left().value();
927 deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
928 if(deleteResult.isRight()){
929 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ",
930 toscaElementVertex.getUniqueId(), deleteResult.right().value());
931 result = Either.right(deleteResult.right().value());
935 result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
940 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
941 Either<GraphVertex, StorageOperationStatus> result = null;
942 Vertex previousCertifiedToscaElement = null;
943 if(majorVersion > 0){
944 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream()
945 .filter(gv->getMinorVersion((String)gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
947 if(CollectionUtils.isEmpty(firstMinorVersionVertex)){
948 result = Either.right(StorageOperationStatus.NOT_FOUND);
950 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
951 if(previousCertifiedToscaElement == null){
952 result = Either.right(StorageOperationStatus.NOT_FOUND);
956 TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
957 if (status != TitanOperationStatus.OK) {
958 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION, previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
959 clonedToscaElement.getUniqueId(), status);
960 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
965 result = Either.left(clonedToscaElement);
970 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
972 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
974 return edges.next().outVertex();
979 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
980 Either<List<GraphVertex>, StorageOperationStatus> result = null;
982 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
983 List<GraphVertex> previosVersions = null;
984 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
985 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
987 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
988 properties.put(GraphPropertyEnum.UUID, uuid);
989 properties.put(GraphPropertyEnum.NAME, componentName);
990 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes= titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
991 if (getToscaElementsRes.isRight()) {
992 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
995 previosVersions = getToscaElementsRes.left().value();
996 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
997 if(deleteResult.isRight()){
998 result = Either.right(deleteResult.right().value());
1002 result = Either.left(previosVersions);
1004 } catch (Exception e){
1005 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
1010 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1012 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1013 String uniqueId = IdBuilderUtils.generateUniqueId();
1014 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1015 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1016 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1017 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1018 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1020 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1021 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1022 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMETER + "0");
1023 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1024 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1025 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
1026 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
1027 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1028 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1030 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
1031 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
1033 if(!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())){
1034 nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
1035 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1037 if(!MapUtils.isEmpty(toscaElementVertex.getJson())){
1038 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1040 return nextVersionToscaElementVertex;
1043 private ComponentParametersView buildComponentParametersViewAfterCheckin() {
1044 ComponentParametersView componentParametersView = new ComponentParametersView();
1045 componentParametersView.disableAll();
1046 componentParametersView.setIgnoreUsers(false);
1047 return componentParametersView;
1050 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
1051 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
1052 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
1053 if(result.isLeft()) {
1054 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
1055 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1056 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
1058 if(result.isLeft()){
1059 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
1060 if(updateRelationsRes.isRight()){
1061 result = Either.right(updateRelationsRes.right().value());
1067 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex){
1069 Either<GraphVertex, StorageOperationStatus> result;
1071 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
1072 if (updateVertexRes.isRight()) {
1073 TitanOperationStatus titatStatus = updateVertexRes.right().value();
1074 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to update state of tosca element vertex {} metadata. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
1075 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
1077 result = Either.left(updateVertexRes.left().value());
1082 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1083 Either<GraphVertex, StorageOperationStatus> result = null;
1084 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
1085 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
1087 if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
1088 //In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
1089 Map<GraphPropertyEnum, Object> vertexProperties = new HashMap<>();
1090 vertexProperties.put(GraphPropertyEnum.STATE, nextState);
1091 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
1092 if (deleteResult.isRight()) {
1093 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
1094 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"failed to update last state relation");
1095 result = Either.right(StorageOperationStatus.INCONSISTENCY);
1098 if(result == null) {
1099 //Remove CHECKOUT relation
1100 Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
1101 if (deleteEdgeResult.isRight()) {
1102 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1103 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
1106 if(result == null) {
1107 //Create CHECKIN relation
1108 Map<EdgePropertyEnum, Object> edgeProperties = new HashMap<>();
1109 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1110 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1111 if (createEdgeRes != TitanOperationStatus.OK) {
1112 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1113 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1116 if(result == null) {
1117 result = Either.left(toscaElementVertex);
1122 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge( GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1123 Either<GraphVertex, StorageOperationStatus> result = null;
1124 if(!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))){
1125 Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1126 if(deleteEdgeRes.isRight()){
1127 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1128 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
1130 if(result == null) {
1131 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1133 if(createEdgeRes != TitanOperationStatus.OK){
1134 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG,"Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1135 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1137 result = Either.left(modifierVertex);
1141 result = Either.left(ownerVertex);
1146 private Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1147 Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1148 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1149 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1150 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1151 return verticesToGetParameters;
1154 private Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1155 Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1156 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1157 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1158 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1159 return verticesToGetParameters;
1162 private Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1163 Map<String, ImmutablePair<GraphPropertyEnum ,JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1164 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1165 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1166 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID,JsonParseFlagEnum.NoParse));
1167 return verticesToGetParameters;
1170 private String getNextVersion(String currVersion) {
1171 String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP);
1172 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1173 return versionParts[0] + VERSION_DELIMETER + minorVersion;
1176 private Integer getMinorVersion(String version) {
1177 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1178 return Integer.parseInt(versionParts[1]);
1181 private Integer getMajorVersion(String version) {
1182 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1183 return Integer.parseInt(versionParts[0]);
1186 private boolean isFirstCheckoutAfterCertification(String version) {
1187 if(Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[1]) == 1){