2 * ============LICENSE_START=======================================================
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
20 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
25 import fj.data.Either;
26 import java.util.ArrayList;
27 import java.util.EnumMap;
28 import java.util.HashMap;
29 import java.util.Iterator;
30 import java.util.List;
32 import java.util.Optional;
33 import java.util.stream.Collectors;
34 import org.apache.commons.collections.CollectionUtils;
35 import org.apache.commons.collections.MapUtils;
36 import org.apache.commons.lang3.StringUtils;
37 import org.apache.commons.lang3.tuple.ImmutablePair;
38 import org.apache.tinkerpop.gremlin.structure.Direction;
39 import org.apache.tinkerpop.gremlin.structure.Edge;
40 import org.apache.tinkerpop.gremlin.structure.Vertex;
41 import org.janusgraph.core.JanusGraphVertex;
42 import org.openecomp.sdc.be.config.ConfigurationManager;
43 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
44 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
45 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
46 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
47 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
48 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
49 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
50 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
51 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
58 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
59 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
60 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
61 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
62 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
63 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
64 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
65 import org.openecomp.sdc.be.model.DistributionStatusEnum;
66 import org.openecomp.sdc.be.model.LifecycleStateEnum;
67 import org.openecomp.sdc.be.model.User;
68 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate;
69 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
70 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
71 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
72 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
73 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
74 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
75 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
76 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
77 import org.openecomp.sdc.common.log.wrappers.Logger;
79 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
81 * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
83 public class ToscaElementLifecycleOperation extends BaseOperation {
85 public static final String VERSION_DELIMITER = ".";
86 public static final String VERSION_DELIMITER_REGEXP = "\\.";
87 private static final String FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS = "Failed to delete last state edge. Status is {}. ";
88 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
89 private static final Logger log = Logger.getLogger(ToscaElementLifecycleOperation.class);
91 static StorageOperationStatus handleFailureToPrepareParameters(final JanusGraphOperationStatus status, final String toscaElementId) {
92 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
93 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
96 static Either<ToscaElement, StorageOperationStatus> getToscaElementFromOperation(final ToscaElementOperation operation, final String uniqueId,
97 final String toscaElementId) {
98 return operation.getToscaElement(uniqueId).right().map(status -> {
99 //We log a potential error we got while retrieving the ToscaElement
100 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, status);
105 private static StorageOperationStatus logDebugMessageAndReturnStorageOperationStatus(final StorageOperationStatus status, final String msg,
106 final Object... args) {
107 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, msg, args);
112 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
115 * @param toscaElementId
120 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId,
123 return janusGraphDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId))
124 .right().map(status -> handleFailureToPrepareParameters(status, toscaElementId)).left().bind(
125 verticesMap -> checkinToscaELement(currState, verticesMap.get(toscaElementId), verticesMap.get(ownerId),
126 verticesMap.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN).left().bind(checkinResult -> {
127 //We retrieve the operation
128 ToscaElementOperation operation = getToscaElementOperation(verticesMap.get(toscaElementId).getLabel());
129 //We retrieve the ToscaElement from the operation
130 return getToscaElementFromOperation(operation, checkinResult.getUniqueId(), toscaElementId);
132 } catch (Exception e) {
133 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occurred during checkin of tosca element {}. {} ", toscaElementId,
135 return Either.right(StorageOperationStatus.GENERAL_ERROR);
140 * Returns vertex presenting owner of tosca element specified by uniqueId
142 * @param toscaElementId
145 public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
146 Either<User, StorageOperationStatus> result = null;
147 GraphVertex toscaElement = null;
148 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
149 if (getToscaElementRes.isRight()) {
150 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
152 if (result == null) {
153 toscaElement = getToscaElementRes.left().value();
154 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
155 if (vertices == null || !vertices.hasNext()) {
156 result = Either.right(StorageOperationStatus.NOT_FOUND);
158 result = Either.left(convertToUser(vertices.next()));
165 * Returns vertex presenting owner of tosca element specified by uniqueId
167 * @param toscaElement
170 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
171 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
172 if (vertices == null || !vertices.hasNext()) {
173 return Either.right(StorageOperationStatus.NOT_FOUND);
175 return Either.left(convertToUser(vertices.next()));
180 * Performs checkout of a tosca element
182 * @param toscaElementId
187 public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
188 Either<ToscaElement, StorageOperationStatus> result = null;
189 Map<String, GraphVertex> vertices = null;
191 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
192 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
193 if (getVerticesRes.isRight()) {
194 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
195 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
197 if (result == null) {
198 vertices = getVerticesRes.left().value();
199 // update previous component if not certified
200 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
201 if (status != StorageOperationStatus.OK) {
202 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
203 result = Either.right(status);
206 if (result == null) {
207 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
208 if (result.isRight()) {
209 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId,
210 result.right().value());
213 } catch (Exception e) {
215 .addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
221 * Performs undo checkout for tosca element
223 * @param toscaElementId
226 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
228 return janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata).right().map(errorStatus -> {
229 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
230 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(errorStatus);
231 }).left().bind(this::retrieveAndUpdatePreviousVersion).left().bind(this::updateEdgeToCatalogRootAndReturnPreVersionElement);
232 } catch (Exception e) {
233 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occurred during undo checkout tosca element {}. {}", toscaElementId,
239 private Either<P2<GraphVertex, JanusGraphVertex>, StorageOperationStatus> retrieveAndUpdatePreviousVersion(final GraphVertex currVersionV) {
240 if (!hasPreviousVersion(currVersionV)) {
241 return Either.left(p(currVersionV, null));
243 // find previous version
244 Iterator<Edge> nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
245 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
246 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ",
247 currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
248 return Either.right(StorageOperationStatus.NOT_FOUND);
250 Vertex preVersionVertex = nextVersionComponentIter.next().outVertex();
251 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
252 if (updateOldResourceResult != StorageOperationStatus.OK) {
253 return Either.right(updateOldResourceResult);
255 P2<GraphVertex, JanusGraphVertex> result = p(currVersionV, (JanusGraphVertex) preVersionVertex);
256 return Either.left(result);
262 private Either<ToscaElement, StorageOperationStatus> updateEdgeToCatalogRootAndReturnPreVersionElement(
263 final P2<GraphVertex, JanusGraphVertex> tuple) {
264 final GraphVertex currVersionV = tuple._1();
265 final JanusGraphVertex preVersionVertex = tuple._2();
266 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRootByUndoCheckout(preVersionVertex, currVersionV);
267 if (updateCatalogRes != StorageOperationStatus.OK) {
268 return Either.right(updateCatalogRes);
270 final ToscaElementOperation operation = getToscaElementOperation(currVersionV.getLabel());
271 return operation.deleteToscaElement(currVersionV).left().bind(discarded -> getUpdatedPreVersionElement(operation, preVersionVertex));
275 private Either<ToscaElement, StorageOperationStatus> getUpdatedPreVersionElement(final ToscaElementOperation operation,
276 final JanusGraphVertex preVersionVertex) {
277 if (preVersionVertex == null) {
278 return Either.left(null);
280 String uniqueIdPreVer = (String) janusGraphDao.getProperty(preVersionVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
281 return operation.getToscaElement(uniqueIdPreVer);
285 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
286 boolean hasPreviousVersion = true;
287 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
288 if (StringUtils.isEmpty(version) || "0.1".equals(version)) {
289 hasPreviousVersion = false;
291 return hasPreviousVersion;
294 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
297 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId)).right()
298 .map(status -> logDebugMessageAndReturnStorageOperationStatus(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status),
299 FAILED_TO_GET_VERTICES, toscaElementId)).left().bind(verticesRes -> {
300 GraphVertex toscaElement = verticesRes.get(toscaElementId);
301 GraphVertex modifier = verticesRes.get(modifierId);
302 Integer majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
303 return handleRelationsBeforeCertifyingAndProcessClone(toscaElement, modifier, majorVersion);
305 } catch (Exception e) {
306 return Either.right(logDebugMessageAndReturnStorageOperationStatus(StorageOperationStatus.GENERAL_ERROR,
307 "Exception occurred during certification tosca element {}.", toscaElementId, e));
311 private Either<ToscaElement, StorageOperationStatus> handleRelationsBeforeCertifyingAndProcessClone(GraphVertex toscaElement,
312 GraphVertex modifier, Integer majorVersion) {
313 StorageOperationStatus status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
314 if (status != StorageOperationStatus.OK) {
315 return Either.right(logDebugMessageAndReturnStorageOperationStatus(status,
316 "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status));
318 return cloneToscaElementAndHandleRelations(toscaElement, modifier, majorVersion);
322 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementAndHandleRelations(GraphVertex toscaElement, GraphVertex modifier,
323 Integer majorVersion) {
324 return cloneToscaElementForCertify(toscaElement, modifier, majorVersion).right()
325 .map(status -> logDebugMessageAndReturnStorageOperationStatus(status, "Failed to clone tosca element during certification. ")).left()
326 .bind(certifiedToscaElement -> handleRelationsOfNewestCertifiedToscaElementAndReturn(toscaElement, certifiedToscaElement));
329 private Either<ToscaElement, StorageOperationStatus> handleRelationsOfNewestCertifiedToscaElementAndReturn(GraphVertex toscaElement,
330 GraphVertex certifiedToscaElement) {
331 StorageOperationStatus status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
332 if (status != StorageOperationStatus.OK) {
333 return Either.right(logDebugMessageAndReturnStorageOperationStatus(status,
334 "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status));
336 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
340 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
341 JanusGraphOperationStatus createVersionEdgeStatus = janusGraphDao
342 .createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
343 if (createVersionEdgeStatus != JanusGraphOperationStatus.OK) {
345 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=",
346 toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(), createVersionEdgeStatus);
347 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createVersionEdgeStatus);
349 return StorageOperationStatus.OK;
352 public Either<GraphVertex, JanusGraphOperationStatus> findUser(String userId) {
353 return findUserVertex(userId);
356 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
357 Either<Boolean, StorageOperationStatus> result = Either.left(true);
358 for (GraphVertex resourceToDelete : toscaElements) {
359 if (!(resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
360 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
361 if (deleteElementRes.isRight()) {
363 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(),
364 deleteElementRes.right().value());
365 result = Either.right(deleteElementRes.right().value());
373 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier,
374 Integer majorVersion) {
375 StorageOperationStatus result = null;
376 if (majorVersion > 0) {
377 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
378 if (findRes.isRight()) {
379 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ",
380 toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
381 result = findRes.right().value();
383 if (result == null) {
384 Vertex lastCertifiedVertex = findRes.left().value();
385 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
386 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
387 JanusGraphOperationStatus status = janusGraphDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
388 if (status != JanusGraphOperationStatus.OK) {
389 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of tosca element {} to [{}]. Status is {}",
390 toscaElement.getUniqueId(), false, status);
391 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
393 // remove previous certified version from the catalog
394 GraphVertex lastCertifiedV = new GraphVertex();
395 lastCertifiedV.setVertex((JanusGraphVertex) lastCertifiedVertex);
396 lastCertifiedV.setUniqueId(
397 (String) janusGraphDao.getProperty((JanusGraphVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
398 lastCertifiedV.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT,
399 (Boolean) janusGraphDao.getProperty((JanusGraphVertex) lastCertifiedVertex, GraphPropertyEnum.IS_ABSTRACT.getProperty()));
400 StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
401 if (res != StorageOperationStatus.OK) {
406 if (result == null) {
407 result = StorageOperationStatus.OK;
412 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
413 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
416 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
417 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
418 return Either.left(vertex);
420 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
421 if (!edgeIter.hasNext()) {
422 return Either.right(StorageOperationStatus.NOT_FOUND);
424 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
427 private boolean isCertifiedVersion(String version) {
428 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
429 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
435 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
436 StorageOperationStatus result = StorageOperationStatus.OK;
437 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
438 if (!previousVersion.endsWith(".0")) {
440 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element",
441 previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
442 Map<String, Object> propertiesToUpdate = new HashMap<>();
443 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
444 Map<String, Object> jsonMetadataMap = JsonParserUtils
445 .toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
446 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
447 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
448 janusGraphDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
449 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
450 if (!edgesIter.hasNext()) {
451 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ",
452 previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
453 result = StorageOperationStatus.NOT_FOUND;
455 Edge lastStateEdge = edgesIter.next();
456 Vertex lastModifier = lastStateEdge.outVertex();
457 JanusGraphOperationStatus replaceRes = janusGraphDao
458 .replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
459 if (replaceRes != JanusGraphOperationStatus.OK) {
461 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE,
462 EdgeLabelEnum.STATE, replaceRes);
463 result = StorageOperationStatus.INCONSISTENCY;
464 if (replaceRes != JanusGraphOperationStatus.INVALID_ID) {
465 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(replaceRes);
469 } catch (Exception e) {
471 .addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ",
478 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
479 StorageOperationStatus result = null;
480 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
481 String toscaElementId = toscaElementVertex.getUniqueId();
482 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
483 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
484 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
485 if (updateVertexRes.isRight()) {
486 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
487 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is {}",
488 toscaElementVertex.getUniqueId(), titatStatus);
489 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
491 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = null;
492 if (result == null) {
494 .addRecordToLog(log, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE,
495 EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
496 deleteEdgeRes = janusGraphDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
497 if (deleteEdgeRes.isRight()) {
498 JanusGraphOperationStatus janusGraphStatus = deleteEdgeRes.right().value();
499 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ",
500 EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, janusGraphStatus);
501 if (!janusGraphStatus.equals(JanusGraphOperationStatus.INVALID_ID)) {
502 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphStatus);
504 result = StorageOperationStatus.INCONSISTENCY;
508 if (result == null) {
509 JanusGraphOperationStatus createEdgeRes = janusGraphDao
510 .createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
511 if (createEdgeRes != JanusGraphOperationStatus.OK) {
512 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes);
516 if (result == null) {
517 result = StorageOperationStatus.OK;
522 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
523 Either<ToscaElement, StorageOperationStatus> result = null;
524 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
525 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
526 // check if component with the next version doesn't exist.
527 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
528 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
529 Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
530 String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
531 String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
532 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
533 "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
534 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(),
535 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
536 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
538 if (result == null) {
539 toscaElementVertex.getOrSetDefaultInstantiationTypeForToscaElementJson();
540 cloneResult = operation
541 .cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
542 if (cloneResult.isRight()) {
543 result = Either.right(cloneResult.right().value());
546 GraphVertex clonedVertex = null;
547 if (result == null) {
548 clonedVertex = cloneResult.left().value();
549 JanusGraphOperationStatus status = janusGraphDao
550 .createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
551 if (status != JanusGraphOperationStatus.OK) {
552 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
553 "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
554 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
555 cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
556 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
559 if (result == null) {
560 Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
561 GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
562 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
563 if (updateCatalogRes != StorageOperationStatus.OK) {
564 return Either.right(updateCatalogRes);
566 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
567 if (result.isRight()) {
570 ToscaElement toscaElement = result.left().value();
571 if (toscaElement.getToscaType() == ToscaElementTypeEnum.TOPOLOGY_TEMPLATE) {
572 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
578 private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex,
579 Either<ToscaElement, StorageOperationStatus> result,
580 ToscaElementOperation operation, GraphVertex clonedVertex,
581 ToscaElement toscaElement) {
582 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
583 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
584 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
585 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
586 Map<String, ToscaElement> origCompMap = new HashMap<>();
587 if (instInputs == null) {
588 instInputs = new HashMap<>();
590 if (instGroups == null) {
591 instGroups = new HashMap<>();
593 if (instArtifactsMap == null) {
594 instArtifactsMap = new HashMap<>();
596 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
597 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
598 boolean needUpdateComposition = false;
599 if (instancesMap != null && !instancesMap.isEmpty()) {
600 for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
602 .addRecordToLog(log, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
603 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
604 collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
606 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
607 if (needUpdateComposition) {
608 instancesMap.put(vfInst.getUniqueId(), vfInst);
612 .addRecordToLog(log, LogLevelEnum.DEBUG, "before add to graph instInputs {} instGroups {} needUpdateComposition {}", instInputs,
613 instGroups, needUpdateComposition);
614 if (!instInputs.isEmpty()) {
615 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
616 GraphVertex toscaDataVertex = null;
617 Either<GraphVertex, JanusGraphOperationStatus> instInpVertexEither = janusGraphDao
618 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
619 if (instInpVertexEither.isLeft()) {
620 toscaDataVertex = instInpVertexEither.left().value();
622 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex,
624 if (status != StorageOperationStatus.OK) {
625 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
626 result = Either.right(status);
630 if (!instGroups.isEmpty()) {
631 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
632 GraphVertex toscaDataVertex = null;
633 Either<GraphVertex, JanusGraphOperationStatus> instGrVertexEither = janusGraphDao
634 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
635 if (instGrVertexEither.isLeft()) {
636 toscaDataVertex = instGrVertexEither.left().value();
638 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex,
640 if (status != StorageOperationStatus.OK) {
641 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
642 result = Either.right(status);
646 if (needUpdateComposition) {
647 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before update Instances ");
648 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
649 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
650 compositionDataDefinition.setComponentInstances(instancesMap);
651 Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(clonedVertex);
652 if (updateElement.isRight()) {
653 JanusGraphOperationStatus status = updateElement.right().value();
654 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
655 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
659 result = operation.getToscaElement(clonedVertex.getUniqueId());
661 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
666 // TODO remove after jsonModelMigration
667 public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
668 return fixToscaComponentName(vfInst, origCompMap);
671 private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
672 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
673 String ciUid = vfInst.getUniqueId();
674 String origCompUid = vfInst.getComponentUid();
675 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid,
676 origCompUid, vfInst.getOriginType());
677 ToscaElement origComp = null;
678 if (!origCompMap.containsKey(origCompUid)) {
679 Either<ToscaElement, StorageOperationStatus> origCompEither;
680 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
681 origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
683 origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
685 if (origCompEither.isRight()) {
687 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
690 origComp = origCompEither.left().value();
691 origCompMap.put(origCompUid, origComp);
693 origComp = origCompMap.get(origCompUid);
695 String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
696 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
697 vfInst.setToscaComponentName(toscaName);
703 private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups,
704 Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
705 boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
706 String ciUid = vfInst.getUniqueId();
707 String origCompUid = vfInst.getComponentUid();
709 .addRecordToLog(log, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
710 TopologyTemplate origComp = null;
711 if (!origCompMap.containsKey(origCompUid)) {
712 Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
713 if (origCompEither.isRight()) {
715 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
718 origComp = (TopologyTemplate) origCompEither.left().value();
719 origCompMap.put(origCompUid, origComp);
721 origComp = (TopologyTemplate) origCompMap.get(origCompUid);
723 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
724 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
725 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
726 if (origInputs != null) {
727 if (!instInputs.containsKey(ciUid)) {
728 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
729 instInputs.put(ciUid, instProperties);
731 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
732 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
733 origInputs.forEach((propName, propMap) -> {
734 if (!instProp.containsKey(propName)) {
735 instProp.put(propName, propMap);
739 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
741 if (isAddInstGroup) {
742 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before create group instance. ");
743 List<GroupDataDefinition> filteredGroups = null;
744 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ",
745 filteredGroups == null ? 0 : filteredGroups.size());
746 if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
747 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
749 .addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
751 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ",
752 filteredGroups == null ? 0 : filteredGroups.size());
753 if (CollectionUtils.isNotEmpty(filteredGroups)) {
754 MapArtifactDataDefinition instArifacts = null;
755 if (!instArtifactsMap.containsKey(ciUid)) {
756 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "istance artifacts not found ");
757 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
758 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
759 addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS,
760 VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
761 instArtifactsMap.put(ciUid, instArifacts);
763 instArifacts = instArtifactsMap.get(ciUid);
765 if (instArifacts != null) {
766 Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
767 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ",
768 instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
769 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
770 for (GroupDataDefinition group : filteredGroups) {
771 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "create new groupInstance {} ", group.getName());
772 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
773 List<String> artifactsUid = new ArrayList<>();
774 List<String> artifactsId = new ArrayList<>();
775 if (instDeplArtifMap != null) {
776 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
777 Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
778 if (op.isPresent()) {
779 artifactsUid.add(artifact.getArtifactUUID());
780 artifactsId.add(artifact.getUniqueId());
784 groupInstance.setGroupInstanceArtifacts(artifactsId);
785 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
786 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
788 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
789 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
796 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
797 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
798 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
799 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
800 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
801 nextVersionToscaElementVertex.setUniqueId(uniqueId);
802 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
803 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
804 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
805 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
806 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
807 if (isFirstCheckoutAfterCertification(nextVersion)) {
808 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
810 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
811 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
812 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
813 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
814 nextVersionToscaElementVertex
815 .addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
817 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
818 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
819 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
821 long currTime = System.currentTimeMillis();
822 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
823 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
824 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
825 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
826 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
827 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL,
828 ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
830 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
831 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
833 return nextVersionToscaElementVertex;
836 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex,
837 Integer majorVersion) {
838 return getToscaElementOperation(toscaElementVertex.getLabel())
839 .cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex)
841 status -> logDebugMessageAndReturnStorageOperationStatus(status, "Failed to clone tosca element {} for certification. Status is {}. ",
842 toscaElementVertex.getUniqueId(), status)).left().bind(
843 clonedToscaElement -> updateEdgesDeleteNotCertifiedVersionsAndHandlePreviousVersions(clonedToscaElement, toscaElementVertex,
847 private Either<GraphVertex, StorageOperationStatus> updateEdgesDeleteNotCertifiedVersionsAndHandlePreviousVersions(GraphVertex clonedToscaElement,
848 GraphVertex toscaElementVertex,
849 Integer majorVersion) {
850 StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
851 if (updateEdgeToCatalog != StorageOperationStatus.OK) {
852 return Either.right(updateEdgeToCatalog);
854 Either<List<GraphVertex>, StorageOperationStatus> deleteResultEither = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
855 if (deleteResultEither == null) {
856 return Either.right(logDebugMessageAndReturnStorageOperationStatus(StorageOperationStatus.GENERAL_ERROR,
857 "Failed to delete all previous not certified versions of tosca element {}. Null value returned.",
858 toscaElementVertex.getUniqueId()));
860 return deleteResultEither.right().map(status -> logDebugMessageAndReturnStorageOperationStatus(status,
861 "Failed to delete all previous not certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(),
862 status)).left().bind(deleteResult -> handlePreviousVersionRelation(clonedToscaElement, deleteResult, majorVersion));
867 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement,
868 List<GraphVertex> deletedVersions, Integer majorVersion) {
869 Either<GraphVertex, StorageOperationStatus> result = null;
870 Vertex previousCertifiedToscaElement = null;
871 if (majorVersion > 0) {
872 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream()
873 .filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
874 if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
875 result = Either.right(StorageOperationStatus.NOT_FOUND);
877 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
878 if (previousCertifiedToscaElement == null) {
879 result = Either.right(StorageOperationStatus.NOT_FOUND);
882 if (result == null) {
883 JanusGraphOperationStatus status = janusGraphDao
884 .createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
885 if (status != JanusGraphOperationStatus.OK) {
886 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
887 "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ",
888 EdgeLabelEnum.VERSION, previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()),
889 clonedToscaElement.getUniqueId(), status);
890 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
894 if (result == null) {
895 result = Either.left(clonedToscaElement);
900 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
901 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
902 if (edges.hasNext()) {
903 return edges.next().outVertex();
908 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
909 Either<List<GraphVertex>, StorageOperationStatus> result = null;
910 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
911 List<GraphVertex> previosVersions = null;
912 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
913 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
915 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
916 properties.put(GraphPropertyEnum.UUID, uuid);
917 properties.put(GraphPropertyEnum.NAME, componentName);
918 Either<List<GraphVertex>, JanusGraphOperationStatus> getToscaElementsRes = janusGraphDao
919 .getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
920 if (getToscaElementsRes.isRight()) {
921 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementsRes.right().value()));
923 if (result == null) {
924 previosVersions = getToscaElementsRes.left().value();
925 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
926 if (deleteResult.isRight()) {
927 result = Either.right(deleteResult.right().value());
930 if (result == null) {
931 result = Either.left(previosVersions);
933 } catch (Exception e) {
935 .addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occurred during deleting all tosca elements by UUID {} and name {}. {} ", uuid,
936 componentName, e.getMessage());
941 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
942 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
943 String uniqueId = IdBuilderUtils.generateUniqueId();
944 Map<GraphPropertyEnum, Object> metadataProperties = new EnumMap<>(toscaElementVertex.getMetadataProperties());
945 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
946 nextVersionToscaElementVertex.setUniqueId(uniqueId);
947 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
948 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
949 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
950 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
951 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMITER + "0");
952 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
953 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
954 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
955 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
956 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
957 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
958 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
959 nextVersionToscaElementVertex
960 .addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
962 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
963 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
964 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
966 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
967 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
969 return nextVersionToscaElementVertex;
972 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex,
973 GraphVertex ownerVertex, GraphVertex modifierVertex,
974 LifecycleStateEnum nextState) {
975 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
976 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
977 if (result.isLeft()) {
978 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
979 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
980 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
982 if (result.isLeft()) {
983 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
984 if (updateRelationsRes.isRight()) {
985 result = Either.right(updateRelationsRes.right().value());
991 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
992 Either<GraphVertex, StorageOperationStatus> result;
993 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
994 if (updateVertexRes.isRight()) {
995 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
996 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is {}",
997 toscaElementVertex.getUniqueId(), titatStatus);
998 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus));
1000 result = Either.left(updateVertexRes.left().value());
1005 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex,
1006 GraphVertex ownerVertex, GraphVertex modifierVertex) {
1007 Either<GraphVertex, StorageOperationStatus> result = null;
1008 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
1009 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
1010 // Remove CHECKOUT relation
1011 Either<Edge, JanusGraphOperationStatus> deleteEdgeResult = janusGraphDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
1012 if (deleteEdgeResult.isRight()) {
1013 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1014 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeResult.right().value()));
1016 if (result == null) {
1017 // Create CHECKIN relation
1018 Map<EdgePropertyEnum, Object> edgeProperties = new EnumMap<>(EdgePropertyEnum.class);
1019 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1020 JanusGraphOperationStatus createEdgeRes = janusGraphDao
1021 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1022 if (createEdgeRes != JanusGraphOperationStatus.OK) {
1023 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1024 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
1027 if (result == null) {
1028 result = Either.left(toscaElementVertex);
1033 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex,
1034 GraphVertex modifierVertex) {
1035 Either<GraphVertex, StorageOperationStatus> result = null;
1036 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID)
1037 .equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
1038 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = janusGraphDao
1039 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1040 if (deleteEdgeRes.isRight()) {
1041 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}",
1042 ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1043 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeRes.right().value()));
1045 if (result == null) {
1046 JanusGraphOperationStatus createEdgeRes = janusGraphDao
1047 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1048 if (createEdgeRes != JanusGraphOperationStatus.OK) {
1049 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}",
1050 modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1051 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
1053 result = Either.left(modifierVertex);
1057 result = Either.left(ownerVertex);
1062 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId,
1065 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1066 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1067 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1068 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1069 return verticesToGetParameters;
1072 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(
1073 String toscaElementId, String modifierId, String ownerId) {
1074 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1075 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1076 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1077 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1078 return verticesToGetParameters;
1081 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId,
1084 //Implementation is currently identical
1085 return prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId);
1088 private String getNextCertifiedVersion(String version) {
1089 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1090 Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
1091 return nextMajorVersion + VERSION_DELIMITER + "0";
1094 private String getNextVersion(String currVersion) {
1095 String[] versionParts = currVersion.split(VERSION_DELIMITER_REGEXP);
1096 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1097 return versionParts[0] + VERSION_DELIMITER + minorVersion;
1100 private Integer getMinorVersion(String version) {
1101 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1102 return Integer.parseInt(versionParts[1]);
1105 private Integer getMajorVersion(String version) {
1106 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1107 return Integer.parseInt(versionParts[0]);
1110 private boolean isFirstCheckoutAfterCertification(String version) {
1111 return (Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[0]) != 0
1112 && Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[1]) == 1);
1115 public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId,
1116 String currVersion) {
1117 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
1118 Either<ToscaElement, StorageOperationStatus> result = null;
1119 GraphVertex toscaElement = null;
1120 GraphVertex modifier = null;
1123 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
1124 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
1125 if (getVerticesRes.isRight()) {
1126 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
1127 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
1129 if (result == null) {
1130 toscaElement = getVerticesRes.left().value().get(toscaElementId);
1131 modifier = getVerticesRes.left().value().get(modifierId);
1132 owner = getVerticesRes.left().value().get(ownerId);
1133 StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
1134 if (status != StorageOperationStatus.OK) {
1135 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG,
1136 "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(),
1140 if (result == null) {
1141 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
1142 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1143 toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
1144 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
1145 if (resultUpdate.isRight()) {
1146 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}",
1147 toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
1148 result = Either.right(resultUpdate.right().value());
1151 if (result == null) {
1152 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
1153 result = operation.getToscaElement(toscaElement.getUniqueId());
1156 } catch (Exception e) {
1158 .addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId,
1164 private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
1165 StorageOperationStatus result = null;
1166 JanusGraphOperationStatus status = janusGraphDao
1167 .replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
1168 if (status != JanusGraphOperationStatus.OK) {
1169 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1171 if (result == null) {
1172 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
1173 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
1174 status = janusGraphDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
1175 if (status != JanusGraphOperationStatus.OK) {
1176 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
1177 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1180 if (result == null) {
1181 result = StorageOperationStatus.OK;
1186 private StorageOperationStatus updateEdgeToCatalogRootByUndoCheckout(JanusGraphVertex preV, GraphVertex curV) {
1188 return updateEdgeToCatalogRoot(null, curV);
1190 String uniqueIdPreVer = (String) janusGraphDao.getProperty((JanusGraphVertex) preV, GraphPropertyEnum.UNIQUE_ID.getProperty());
1191 LifecycleStateEnum state = LifecycleStateEnum.findState((String) janusGraphDao.getProperty(preV, GraphPropertyEnum.STATE.getProperty()));
1192 if (state == LifecycleStateEnum.CERTIFIED) {
1193 return updateEdgeToCatalogRoot(null, curV);
1195 return janusGraphDao.getVertexById(uniqueIdPreVer)
1196 .either(l -> updateEdgeToCatalogRoot(l, curV), DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
1199 private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
1200 Either<GraphVertex, JanusGraphOperationStatus> catalog = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
1201 if (catalog.isRight()) {
1202 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
1203 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(catalog.right().value());
1205 GraphVertex catalogV = catalog.left().value();
1206 if (newVersionV != null) {
1207 Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1208 if (isAbstract == null || !isAbstract) {
1209 // create new vertex
1210 JanusGraphOperationStatus result = janusGraphDao.createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
1211 if (result != JanusGraphOperationStatus.OK) {
1212 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}",
1213 newVersionV.getUniqueId(), result);
1214 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(result);
1218 if (prevVersionV != null) {
1219 Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1220 if (isAbstract == null || !isAbstract) {
1221 // if prev == null -> new resource was added
1222 Either<Edge, JanusGraphOperationStatus> deleteResult = janusGraphDao
1223 .deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
1224 if (deleteResult.isRight()) {
1225 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}",
1226 prevVersionV.getUniqueId(), deleteResult.right().value());
1227 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteResult.right().value());
1231 return StorageOperationStatus.OK;