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=========================================================
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
23 import org.janusgraph.core.JanusGraphVertex;
24 import fj.data.Either;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.lang3.tuple.ImmutablePair;
29 import org.apache.tinkerpop.gremlin.structure.Direction;
30 import org.apache.tinkerpop.gremlin.structure.Edge;
31 import org.apache.tinkerpop.gremlin.structure.Vertex;
32 import org.openecomp.sdc.be.config.ConfigurationManager;
33 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
34 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
35 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
36 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
37 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
38 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
39 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
40 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
41 import org.openecomp.sdc.be.datatypes.elements.*;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
44 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
45 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
46 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
47 import org.openecomp.sdc.be.model.DistributionStatusEnum;
48 import org.openecomp.sdc.be.model.LifecycleStateEnum;
49 import org.openecomp.sdc.be.model.User;
50 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate;
51 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
52 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
53 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
54 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
55 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
56 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
57 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
58 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
59 import org.openecomp.sdc.common.log.wrappers.Logger;
62 import java.util.stream.Collectors;
64 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
67 * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
69 public class ToscaElementLifecycleOperation extends BaseOperation {
71 private static final String FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS = "Failed to delete last state edge. Status is {}. ";
72 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
73 public static final String VERSION_DELIMITER = ".";
74 public static final String VERSION_DELIMITER_REGEXP = "\\.";
76 private static final Logger log = Logger.getLogger(ToscaElementLifecycleOperation.class);
79 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
82 * @param toscaElementId
87 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState,
88 String toscaElementId, String modifierId, String ownerId) {
91 .getVerticesByUniqueIdAndParseFlag(
92 prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId))
93 .right().map(status -> handleFailureToPrepareParameters(status, toscaElementId))
98 verticesMap.get(toscaElementId),
99 verticesMap.get(ownerId),
100 verticesMap.get(modifierId),
101 LifecycleStateEnum.NOT_CERTIFIED_CHECKIN
102 ).left().bind(checkinResult -> {
103 //We retrieve the operation
104 ToscaElementOperation operation =
105 getToscaElementOperation(verticesMap.get(toscaElementId).getLabel());
107 //We retrieve the ToscaElement from the operation
108 return getToscaElementFromOperation(operation, checkinResult.getUniqueId(), toscaElementId);
111 } catch (Exception e) {
112 CommonUtility.addRecordToLog(
113 log, LogLevelEnum.DEBUG, "Exception occurred during checkin of tosca element {}. {} ", toscaElementId,
115 return Either.right(StorageOperationStatus.GENERAL_ERROR);
119 static StorageOperationStatus handleFailureToPrepareParameters(final JanusGraphOperationStatus status, final String toscaElementId) {
120 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
121 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
124 static Either<ToscaElement, StorageOperationStatus> getToscaElementFromOperation(final ToscaElementOperation operation,
125 final String uniqueId, final String toscaElementId) {
126 return operation.getToscaElement(uniqueId)
127 .right().map(status -> {
128 //We log a potential error we got while retrieving the ToscaElement
130 .addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}",
131 toscaElementId, status);
137 * Returns vertex presenting owner of tosca element specified by uniqueId
139 * @param toscaElementId
142 public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
143 Either<User, StorageOperationStatus> result = null;
144 GraphVertex toscaElement = null;
145 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = janusGraphDao
146 .getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
147 if (getToscaElementRes.isRight()) {
148 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
150 if (result == null) {
151 toscaElement = getToscaElementRes.left().value();
152 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
153 if (vertices == null || !vertices.hasNext()) {
154 result = Either.right(StorageOperationStatus.NOT_FOUND);
156 result = Either.left(convertToUser(vertices.next()));
163 * Returns vertex presenting owner of tosca element specified by uniqueId
165 * @param toscaElement
168 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
169 Either<User, StorageOperationStatus> result = null;
170 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
171 if (vertices == null || !vertices.hasNext()) {
172 result = Either.right(StorageOperationStatus.NOT_FOUND);
174 result = 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, result.right().value());
213 } catch (Exception e) {
214 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
220 * Performs undo checkout for tosca element
222 * @param toscaElementId
225 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
226 Either<ToscaElement, StorageOperationStatus> result = null;
227 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = null;
228 Iterator<Edge> nextVersionComponentIter = null;
229 ToscaElementOperation operation;
230 Vertex preVersionVertex = null;
232 getToscaElementRes = janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
233 if (getToscaElementRes.isRight()) {
234 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
235 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
237 GraphVertex currVersionV = getToscaElementRes.left().value();
238 if (result == null && hasPreviousVersion(currVersionV)) {
239 // find previous version
240 nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
241 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
242 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
243 result = Either.right(StorageOperationStatus.NOT_FOUND);
245 if (result == null) {
246 preVersionVertex = nextVersionComponentIter.next().outVertex();
247 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
248 if (updateOldResourceResult != StorageOperationStatus.OK) {
249 result = Either.right(updateOldResourceResult);
253 if (result == null) {
254 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRootByUndoCheckout((JanusGraphVertex) preVersionVertex, currVersionV);
255 if (updateCatalogRes != StorageOperationStatus.OK) {
256 return Either.right(updateCatalogRes);
258 operation = getToscaElementOperation(currVersionV.getLabel());
259 result = operation.deleteToscaElement(currVersionV);
260 if (result.isRight()) {
263 if(preVersionVertex != null){
264 String uniqueIdPreVer = (String) janusGraphDao.getProperty((JanusGraphVertex) preVersionVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
265 result = operation.getToscaElement(uniqueIdPreVer);
267 result = Either.left(null);
270 } catch (Exception e) {
271 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
276 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
277 boolean hasPreviousVersion = true;
278 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
279 if (StringUtils.isEmpty(version) || "0.1".equals(version))
280 hasPreviousVersion = false;
281 return hasPreviousVersion;
284 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
285 Either<ToscaElement, StorageOperationStatus> result = null;
286 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
287 GraphVertex toscaElement = null;
288 GraphVertex modifier = null;
289 GraphVertex certifiedToscaElement = null;
290 Integer majorVersion = null;
292 StorageOperationStatus status;
294 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
295 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
296 if (getVerticesRes.isRight()) {
297 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
298 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
300 if (result == null) {
301 toscaElement = getVerticesRes.left().value().get(toscaElementId);
302 modifier = getVerticesRes.left().value().get(modifierId);
303 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
304 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
305 if (status != StorageOperationStatus.OK) {
306 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
309 if (result == null) {
310 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
311 if (cloneRes.isRight()) {
312 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
313 result = Either.right(cloneRes.right().value());
315 certifiedToscaElement = cloneRes.left().value();
316 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
317 if (status != StorageOperationStatus.OK) {
318 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
322 if (result == null) {
323 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
325 } catch (Exception e) {
326 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
331 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
333 JanusGraphOperationStatus createVersionEdgeStatus = janusGraphDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
334 if (createVersionEdgeStatus != JanusGraphOperationStatus.OK) {
335 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
336 createVersionEdgeStatus);
337 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createVersionEdgeStatus);
339 return StorageOperationStatus.OK;
342 public Either<GraphVertex, JanusGraphOperationStatus> findUser(String userId) {
343 return findUserVertex(userId);
346 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
347 Either<Boolean, StorageOperationStatus> result = Either.left(true);
348 for (GraphVertex resourceToDelete : toscaElements) {
349 if (!(resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
350 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
351 if (deleteElementRes.isRight()) {
352 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
353 result = Either.right(deleteElementRes.right().value());
361 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
362 StorageOperationStatus result = null;
363 if (majorVersion > 0) {
364 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
365 if (findRes.isRight()) {
366 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
367 result = findRes.right().value();
369 if (result == null) {
370 Vertex lastCertifiedVertex = findRes.left().value();
371 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
372 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
373 JanusGraphOperationStatus status = janusGraphDao
374 .updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
375 if (status != JanusGraphOperationStatus.OK) {
376 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
377 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
379 // remove previous certified version from the catalog
380 GraphVertex lastCertifiedV = new GraphVertex();
381 lastCertifiedV.setVertex((JanusGraphVertex) lastCertifiedVertex);
382 lastCertifiedV.setUniqueId((String) janusGraphDao
383 .getProperty((JanusGraphVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
384 StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
385 if (res != StorageOperationStatus.OK) {
390 if (result == null) {
391 result = StorageOperationStatus.OK;
396 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
397 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
400 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
401 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
402 return Either.left(vertex);
404 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
405 if (!edgeIter.hasNext()) {
406 return Either.right(StorageOperationStatus.NOT_FOUND);
408 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
411 private boolean isCertifiedVersion(String version) {
412 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
413 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
419 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
421 StorageOperationStatus result = StorageOperationStatus.OK;
422 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
423 if (!previousVersion.endsWith(".0")) {
425 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
427 Map<String, Object> propertiesToUpdate = new HashMap<>();
428 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
429 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
430 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
431 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
433 janusGraphDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
435 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
436 if (!edgesIter.hasNext()) {
437 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
438 result = StorageOperationStatus.NOT_FOUND;
440 Edge lastStateEdge = edgesIter.next();
441 Vertex lastModifier = lastStateEdge.outVertex();
442 JanusGraphOperationStatus replaceRes = janusGraphDao
443 .replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
444 if (replaceRes != JanusGraphOperationStatus.OK) {
445 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
446 result = StorageOperationStatus.INCONSISTENCY;
447 if (replaceRes != JanusGraphOperationStatus.INVALID_ID) {
448 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(replaceRes);
453 } catch (Exception e) {
454 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
460 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
461 StorageOperationStatus result = null;
462 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
463 String toscaElementId = toscaElementVertex.getUniqueId();
464 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
465 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
466 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
467 if (updateVertexRes.isRight()) {
468 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
469 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
470 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
472 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = null;
473 if (result == null) {
474 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
476 deleteEdgeRes = janusGraphDao
477 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
478 if (deleteEdgeRes.isRight()) {
479 JanusGraphOperationStatus janusGraphStatus = deleteEdgeRes.right().value();
480 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, janusGraphStatus);
481 if (!janusGraphStatus.equals(JanusGraphOperationStatus.INVALID_ID)) {
482 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphStatus);
484 result = StorageOperationStatus.INCONSISTENCY;
488 if (result == null) {
489 JanusGraphOperationStatus
490 createEdgeRes = janusGraphDao
491 .createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
492 if (createEdgeRes != JanusGraphOperationStatus.OK) {
493 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes);
497 if (result == null) {
498 result = StorageOperationStatus.OK;
503 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
505 Either<ToscaElement, StorageOperationStatus> result = null;
506 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
507 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
508 // check if component with the next version doesn't exist.
509 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
510 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
511 Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
512 String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
513 String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
514 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
515 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
516 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
518 if (result == null) {
519 toscaElementVertex.getOrSetDefaultInstantiationTypeForToscaElementJson();
520 cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
521 if (cloneResult.isRight()) {
522 result = Either.right(cloneResult.right().value());
525 GraphVertex clonedVertex = null;
526 if (result == null) {
527 clonedVertex = cloneResult.left().value();
528 JanusGraphOperationStatus
529 status = janusGraphDao
530 .createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
531 if (status != JanusGraphOperationStatus.OK) {
532 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
533 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
534 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
537 if (result == null) {
538 Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
539 GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
540 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
541 if (updateCatalogRes != StorageOperationStatus.OK) {
542 return Either.right(updateCatalogRes);
544 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
545 if (result.isRight()) {
548 ToscaElement toscaElement = result.left().value();
549 if (toscaElement.getToscaType() == ToscaElementTypeEnum.TOPOLOGY_TEMPLATE) {
550 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
557 private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
558 ToscaElement toscaElement) {
559 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
560 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
561 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
562 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
563 Map<String, ToscaElement> origCompMap = new HashMap<>();
564 if (instInputs == null) {
565 instInputs = new HashMap<>();
567 if (instGroups == null) {
568 instGroups = new HashMap<>();
570 if (instArtifactsMap == null) {
571 instArtifactsMap = new HashMap<>();
573 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
574 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
575 boolean needUpdateComposition = false;
577 if (instancesMap != null && !instancesMap.isEmpty()) {
578 for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
579 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
580 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
581 collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
583 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
584 if (needUpdateComposition) {
585 instancesMap.put(vfInst.getUniqueId(), vfInst);
588 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add to graph instInputs {} instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
589 if (!instInputs.isEmpty()) {
590 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
591 GraphVertex toscaDataVertex = null;
592 Either<GraphVertex, JanusGraphOperationStatus> instInpVertexEither = janusGraphDao
593 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
594 if (instInpVertexEither.isLeft()) {
595 toscaDataVertex = instInpVertexEither.left().value();
598 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
599 if (status != StorageOperationStatus.OK) {
600 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
601 result = Either.right(status);
606 if (!instGroups.isEmpty()) {
607 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
608 GraphVertex toscaDataVertex = null;
609 Either<GraphVertex, JanusGraphOperationStatus> instGrVertexEither = janusGraphDao
610 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
611 if (instGrVertexEither.isLeft()) {
612 toscaDataVertex = instGrVertexEither.left().value();
615 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
616 if (status != StorageOperationStatus.OK) {
617 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
618 result = Either.right(status);
623 if (needUpdateComposition) {
624 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before update Instances ");
625 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
626 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
627 compositionDataDefinition.setComponentInstances(instancesMap);
628 Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(clonedVertex);
629 if (updateElement.isRight()) {
630 JanusGraphOperationStatus status = updateElement.right().value();
631 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
632 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
637 result = operation.getToscaElement(clonedVertex.getUniqueId());
640 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
645 // TODO remove after jsonModelMigration
646 public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
647 return fixToscaComponentName(vfInst, origCompMap);
650 private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
651 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
652 String ciUid = vfInst.getUniqueId();
653 String origCompUid = vfInst.getComponentUid();
654 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
655 ToscaElement origComp = null;
656 if (!origCompMap.containsKey(origCompUid)) {
657 Either<ToscaElement, StorageOperationStatus> origCompEither;
658 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
659 origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
661 origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
663 if (origCompEither.isRight()) {
664 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
667 origComp = origCompEither.left().value();
668 origCompMap.put(origCompUid, origComp);
670 origComp = origCompMap.get(origCompUid);
672 String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
673 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
674 vfInst.setToscaComponentName(toscaName);
680 private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
681 boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
682 String ciUid = vfInst.getUniqueId();
683 String origCompUid = vfInst.getComponentUid();
684 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
685 TopologyTemplate origComp = null;
686 if (!origCompMap.containsKey(origCompUid)) {
687 Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
688 if (origCompEither.isRight()) {
689 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
692 origComp = (TopologyTemplate) origCompEither.left().value();
693 origCompMap.put(origCompUid, origComp);
695 origComp = (TopologyTemplate) origCompMap.get(origCompUid);
697 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
699 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
700 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
701 if (origInputs != null) {
702 if (!instInputs.containsKey(ciUid)) {
703 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
704 instInputs.put(ciUid, instProperties);
707 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
708 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
709 origInputs.forEach((propName, propMap) -> {
710 if (!instProp.containsKey(propName)) {
711 instProp.put(propName, propMap);
715 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
718 if (isAddInstGroup) {
719 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before create group instance. ");
720 List<GroupDataDefinition> filteredGroups = null;
722 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
723 if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
724 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
725 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
727 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
728 if (CollectionUtils.isNotEmpty(filteredGroups)) {
729 MapArtifactDataDefinition instArifacts = null;
730 if (!instArtifactsMap.containsKey(ciUid)) {
732 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "istance artifacts not found ");
734 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
736 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
737 addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
739 instArtifactsMap.put(ciUid, instArifacts);
742 instArifacts = instArtifactsMap.get(ciUid);
745 if (instArifacts != null) {
746 Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
748 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
749 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
750 for (GroupDataDefinition group : filteredGroups) {
751 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "create new groupInstance {} ", group.getName());
752 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
753 List<String> artifactsUid = new ArrayList<>();
754 List<String> artifactsId = new ArrayList<>();
755 if (instDeplArtifMap!=null) {
756 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
757 Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
758 if (op.isPresent()) {
759 artifactsUid.add(artifact.getArtifactUUID());
760 artifactsId.add(artifact.getUniqueId());
765 groupInstance.setGroupInstanceArtifacts(artifactsId);
766 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
767 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
769 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
770 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
778 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
779 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
780 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
781 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
782 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
783 nextVersionToscaElementVertex.setUniqueId(uniqueId);
784 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
785 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
787 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
788 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
789 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
790 if (isFirstCheckoutAfterCertification(nextVersion)) {
791 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
793 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
794 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
795 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
797 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
798 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
800 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
801 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
802 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
804 long currTime = System.currentTimeMillis();
805 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
806 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
807 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
808 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
809 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
810 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
813 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
814 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
816 return nextVersionToscaElementVertex;
819 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
820 Either<GraphVertex, StorageOperationStatus> result;
821 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
822 GraphVertex clonedToscaElement = null;
823 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
824 if (result.isRight()) {
825 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
827 clonedToscaElement = result.left().value();
828 StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
829 if (updateEdgeToCatalog != StorageOperationStatus.OK) {
830 return Either.right(updateEdgeToCatalog);
832 deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
833 if (deleteResult.isRight()) {
834 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
835 result = Either.right(deleteResult.right().value());
838 if (result.isLeft()) {
839 result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
844 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
845 Either<GraphVertex, StorageOperationStatus> result = null;
846 Vertex previousCertifiedToscaElement = null;
847 if (majorVersion > 0) {
848 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
850 if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
851 result = Either.right(StorageOperationStatus.NOT_FOUND);
853 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
854 if (previousCertifiedToscaElement == null) {
855 result = Either.right(StorageOperationStatus.NOT_FOUND);
858 if (result == null) {
859 JanusGraphOperationStatus
860 status = janusGraphDao
861 .createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
862 if (status != JanusGraphOperationStatus.OK) {
863 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
864 previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
865 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
870 if (result == null) {
871 result = Either.left(clonedToscaElement);
876 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
878 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
879 if (edges.hasNext()) {
880 return edges.next().outVertex();
885 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
886 Either<List<GraphVertex>, StorageOperationStatus> result = null;
888 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
889 List<GraphVertex> previosVersions = null;
890 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
891 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
893 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
894 properties.put(GraphPropertyEnum.UUID, uuid);
895 properties.put(GraphPropertyEnum.NAME, componentName);
896 Either<List<GraphVertex>, JanusGraphOperationStatus> getToscaElementsRes = janusGraphDao
897 .getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
898 if (getToscaElementsRes.isRight()) {
899 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementsRes.right().value()));
901 if (result == null) {
902 previosVersions = getToscaElementsRes.left().value();
903 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
904 if (deleteResult.isRight()) {
905 result = Either.right(deleteResult.right().value());
908 if (result == null) {
909 result = Either.left(previosVersions);
911 } catch (Exception e) {
912 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
917 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
919 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
920 String uniqueId = IdBuilderUtils.generateUniqueId();
921 Map<GraphPropertyEnum, Object> metadataProperties = new EnumMap<>(toscaElementVertex.getMetadataProperties());
922 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
923 nextVersionToscaElementVertex.setUniqueId(uniqueId);
924 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
925 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
927 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
928 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
929 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMITER + "0");
930 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
931 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
932 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
933 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
934 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
935 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
937 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
938 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
940 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
941 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
942 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
944 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
945 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
947 return nextVersionToscaElementVertex;
951 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
952 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
953 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
954 if (result.isLeft()) {
955 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
956 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
957 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
959 if (result.isLeft()) {
960 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
961 if (updateRelationsRes.isRight()) {
962 result = Either.right(updateRelationsRes.right().value());
968 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
970 Either<GraphVertex, StorageOperationStatus> result;
972 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
973 if (updateVertexRes.isRight()) {
974 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
975 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
976 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus));
978 result = Either.left(updateVertexRes.left().value());
983 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
984 Either<GraphVertex, StorageOperationStatus> result = null;
985 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
986 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
988 // Remove CHECKOUT relation
989 Either<Edge, JanusGraphOperationStatus> deleteEdgeResult = janusGraphDao
990 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
991 if (deleteEdgeResult.isRight()) {
992 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
993 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeResult.right().value()));
996 if (result == null) {
997 // Create CHECKIN relation
998 Map<EdgePropertyEnum, Object> edgeProperties = new EnumMap<>(EdgePropertyEnum.class);
999 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1000 JanusGraphOperationStatus
1001 createEdgeRes = janusGraphDao
1002 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1003 if (createEdgeRes != JanusGraphOperationStatus.OK) {
1004 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1005 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
1008 if (result == null) {
1009 result = Either.left(toscaElementVertex);
1014 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1015 Either<GraphVertex, StorageOperationStatus> result = null;
1016 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
1017 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = janusGraphDao
1018 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1019 if (deleteEdgeRes.isRight()) {
1020 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1021 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeRes.right().value()));
1023 if (result == null) {
1024 JanusGraphOperationStatus createEdgeRes = janusGraphDao
1025 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1027 if (createEdgeRes != JanusGraphOperationStatus.OK) {
1028 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1029 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
1031 result = Either.left(modifierVertex);
1035 result = Either.left(ownerVertex);
1040 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1041 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1042 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1043 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1044 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1045 return verticesToGetParameters;
1048 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1049 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1050 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1051 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1052 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1053 return verticesToGetParameters;
1056 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1057 //Implementation is currently identical
1058 return prepareParametersToGetVerticesForRequestCertification(toscaElementId,modifierId, ownerId);
1061 private String getNextCertifiedVersion(String version) {
1062 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1063 Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
1064 return nextMajorVersion + VERSION_DELIMITER + "0";
1067 private String getNextVersion(String currVersion) {
1068 String[] versionParts = currVersion.split(VERSION_DELIMITER_REGEXP);
1069 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1070 return versionParts[0] + VERSION_DELIMITER + minorVersion;
1073 private Integer getMinorVersion(String version) {
1074 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1075 return Integer.parseInt(versionParts[1]);
1078 private Integer getMajorVersion(String version) {
1079 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1080 return Integer.parseInt(versionParts[0]);
1083 private boolean isFirstCheckoutAfterCertification(String version) {
1084 return (Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[1]) == 1);
1087 public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
1088 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
1089 Either<ToscaElement, StorageOperationStatus> result = null;
1090 GraphVertex toscaElement = null;
1091 GraphVertex modifier = null;
1094 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
1095 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
1096 if (getVerticesRes.isRight()) {
1097 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
1098 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
1100 if (result == null) {
1101 toscaElement = getVerticesRes.left().value().get(toscaElementId);
1102 modifier = getVerticesRes.left().value().get(modifierId);
1103 owner = getVerticesRes.left().value().get(ownerId);
1105 StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
1106 if (status != StorageOperationStatus.OK) {
1107 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
1110 if (result == null) {
1111 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
1113 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1114 toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
1116 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
1117 if (resultUpdate.isRight()) {
1118 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
1119 result = Either.right(resultUpdate.right().value());
1122 if (result == null) {
1123 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
1124 result = operation.getToscaElement(toscaElement.getUniqueId());
1128 } catch (Exception e) {
1129 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
1134 private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
1136 StorageOperationStatus result = null;
1137 JanusGraphOperationStatus status = janusGraphDao
1138 .replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
1139 if (status != JanusGraphOperationStatus.OK) {
1140 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1142 if (result == null) {
1143 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
1144 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
1145 status = janusGraphDao
1146 .createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
1147 if (status != JanusGraphOperationStatus.OK) {
1148 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
1149 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1152 if (result == null) {
1153 result = StorageOperationStatus.OK;
1158 private StorageOperationStatus updateEdgeToCatalogRootByUndoCheckout(JanusGraphVertex preV, GraphVertex curV) {
1160 return updateEdgeToCatalogRoot(null, curV);
1162 String uniqueIdPreVer = (String) janusGraphDao
1163 .getProperty((JanusGraphVertex) preV, GraphPropertyEnum.UNIQUE_ID.getProperty());
1164 LifecycleStateEnum state = LifecycleStateEnum.findState((String) janusGraphDao
1165 .getProperty(preV, GraphPropertyEnum.STATE.getProperty()));
1166 if (state == LifecycleStateEnum.CERTIFIED) {
1167 return updateEdgeToCatalogRoot(null, curV);
1169 return janusGraphDao.getVertexById(uniqueIdPreVer)
1170 .either(l -> updateEdgeToCatalogRoot(l, curV),
1171 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
1174 private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
1175 Either<GraphVertex, JanusGraphOperationStatus> catalog = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
1176 if (catalog.isRight()) {
1177 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
1178 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(catalog.right().value());
1180 GraphVertex catalogV = catalog.left().value();
1181 if (newVersionV != null) {
1182 Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1184 if ( isAbstract == null || !isAbstract ) {
1185 // no new vertex, only delete previous
1186 JanusGraphOperationStatus
1187 result = janusGraphDao
1188 .createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
1189 if (result != JanusGraphOperationStatus.OK) {
1190 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
1191 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(result);
1195 if (prevVersionV != null) {
1196 Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1197 if (isAbstract == null || !isAbstract) {
1198 // if prev == null -> new resource was added
1199 Either<Edge, JanusGraphOperationStatus> deleteResult = janusGraphDao
1200 .deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
1201 if (deleteResult.isRight()) {
1202 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
1203 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteResult.right().value());
1207 return StorageOperationStatus.OK;