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.jsontitan.operations;
23 import com.thinkaurelius.titan.core.TitanVertex;
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.jsongraph.GraphVertex;
34 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
35 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
36 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
37 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
38 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
39 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
40 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
41 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
42 import org.openecomp.sdc.be.datatypes.elements.*;
43 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
44 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
45 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
46 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
47 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
48 import org.openecomp.sdc.be.model.ComponentParametersView;
49 import org.openecomp.sdc.be.model.DistributionStatusEnum;
50 import org.openecomp.sdc.be.model.LifecycleStateEnum;
51 import org.openecomp.sdc.be.model.User;
52 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
53 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
54 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
55 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
56 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
57 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
58 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
59 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
60 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
61 import org.openecomp.sdc.common.log.wrappers.Logger;
64 import java.util.stream.Collectors;
66 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
69 * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
71 public class ToscaElementLifecycleOperation extends BaseOperation {
73 private static final String FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS = "Failed to delete last state edge. Status is {}. ";
74 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
75 public static final String VERSION_DELIMITER = ".";
76 public static final String VERSION_DELIMITER_REGEXP = "\\.";
78 private static final Logger log = Logger.getLogger(ToscaElementLifecycleOperation.class);
81 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
84 * @param toscaElementId
89 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
90 Either<GraphVertex, StorageOperationStatus> updateResult = null;
91 Either<ToscaElement, StorageOperationStatus> result = null;
92 Map<String, GraphVertex> vertices = null;
93 ToscaElementOperation operation;
95 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
96 if (getVerticesRes.isRight()) {
97 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
98 updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
100 vertices = getVerticesRes.left().value();
101 updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
103 if (updateResult.isLeft()) {
104 operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
105 result = operation.getToscaElement(updateResult.left().value().getUniqueId());
106 if (result.isRight()) {
107 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
110 result = Either.right(updateResult.right().value());
112 } catch (Exception e) {
113 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
119 * Returns vertex presenting owner of tosca element specified by uniqueId
121 * @param toscaElementId
124 public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
125 Either<User, StorageOperationStatus> result = null;
126 GraphVertex toscaElement = null;
127 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
128 if (getToscaElementRes.isRight()) {
129 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
131 if (result == null) {
132 toscaElement = getToscaElementRes.left().value();
133 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
134 if (vertices == null || !vertices.hasNext()) {
135 result = Either.right(StorageOperationStatus.NOT_FOUND);
137 result = Either.left(convertToUser(vertices.next()));
144 * Returns vertex presenting owner of tosca element specified by uniqueId
146 * @param toscaElement
149 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
150 Either<User, StorageOperationStatus> result = null;
151 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
152 if (vertices == null || !vertices.hasNext()) {
153 result = Either.right(StorageOperationStatus.NOT_FOUND);
155 result = Either.left(convertToUser(vertices.next()));
161 * Performs checkout of a tosca element
163 * @param toscaElementId
168 public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
169 Either<ToscaElement, StorageOperationStatus> result = null;
170 Map<String, GraphVertex> vertices = null;
172 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
173 if (getVerticesRes.isRight()) {
174 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
175 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
177 if (result == null) {
178 vertices = getVerticesRes.left().value();
179 // update previous component if not certified
180 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
181 if (status != StorageOperationStatus.OK) {
182 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
183 result = Either.right(status);
186 if (result == null) {
187 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
188 if (result.isRight()) {
189 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
193 } catch (Exception e) {
194 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
200 * Performs undo checkout for tosca element
202 * @param toscaElementId
205 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
206 Either<ToscaElement, StorageOperationStatus> result = null;
207 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
208 Iterator<Edge> nextVersionComponentIter = null;
209 ToscaElementOperation operation;
210 Vertex preVersionVertex = null;
212 getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
213 if (getToscaElementRes.isRight()) {
214 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
215 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
217 GraphVertex currVersionV = getToscaElementRes.left().value();
218 if (result == null && hasPreviousVersion(currVersionV)) {
219 // find previous version
220 nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
221 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
222 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
223 result = Either.right(StorageOperationStatus.NOT_FOUND);
225 if (result == null) {
226 preVersionVertex = nextVersionComponentIter.next().outVertex();
227 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
228 if (updateOldResourceResult != StorageOperationStatus.OK) {
229 result = Either.right(updateOldResourceResult);
233 if (result == null) {
234 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRootByUndoCheckout((TitanVertex) preVersionVertex, currVersionV);
235 if (updateCatalogRes != StorageOperationStatus.OK) {
236 return Either.right(updateCatalogRes);
238 operation = getToscaElementOperation(currVersionV.getLabel());
239 result = operation.deleteToscaElement(currVersionV);
241 } catch (Exception e) {
242 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
247 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
248 boolean hasPreviousVersion = true;
249 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
250 if (StringUtils.isEmpty(version) || "0.1".equals(version))
251 hasPreviousVersion = false;
252 return hasPreviousVersion;
256 * Performs request certification for tosca element
258 * @param toscaElementId
263 public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
264 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
265 Either<ToscaElement, StorageOperationStatus> result = null;
266 GraphVertex toscaElement = null;
267 GraphVertex modifier = null;
270 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
271 if (getVerticesRes.isRight()) {
272 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
273 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
275 if (result == null) {
276 toscaElement = getVerticesRes.left().value().get(toscaElementId);
277 modifier = getVerticesRes.left().value().get(modifierId);
278 owner = getVerticesRes.left().value().get(ownerId);
280 StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
281 if (status != StorageOperationStatus.OK) {
282 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
285 if (result == null) {
286 LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
288 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
289 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
291 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
292 if (resultUpdate.isRight()) {
293 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
294 result = Either.right(resultUpdate.right().value());
297 if (result == null) {
298 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
299 result = operation.getToscaElement(toscaElement.getUniqueId());
303 } catch (Exception e) {
304 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
310 * Starts certification of tosca element
312 * @param toscaElementId
317 public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
318 Either<ToscaElement, StorageOperationStatus> result = null;
319 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
320 GraphVertex toscaElement = null;
321 GraphVertex modifier = null;
324 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
325 if (getVerticesRes.isRight()) {
326 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
327 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
329 if (result == null) {
330 toscaElement = getVerticesRes.left().value().get(toscaElementId);
331 modifier = getVerticesRes.left().value().get(modifierId);
332 owner = getVerticesRes.left().value().get(ownerId);
334 StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
335 if (status != StorageOperationStatus.OK) {
336 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations during certification of tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
339 if (result == null) {
340 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
342 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
343 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
345 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
346 if (resultUpdate.isRight()) {
347 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
348 result = Either.right(resultUpdate.right().value());
351 if (result == null) {
352 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
353 result = operation.getToscaElement(toscaElement.getUniqueId());
355 } catch (Exception e) {
356 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
361 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
362 Either<ToscaElement, StorageOperationStatus> result = null;
363 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
364 GraphVertex toscaElement = null;
365 GraphVertex modifier = null;
366 GraphVertex certifiedToscaElement = null;
367 Integer majorVersion = null;
369 StorageOperationStatus status;
371 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
372 if (getVerticesRes.isRight()) {
373 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
374 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
376 if (result == null) {
377 toscaElement = getVerticesRes.left().value().get(toscaElementId);
378 modifier = getVerticesRes.left().value().get(modifierId);
379 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
380 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
381 if (status != StorageOperationStatus.OK) {
382 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
385 if (result == null) {
386 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
387 if (cloneRes.isRight()) {
388 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
389 result = Either.right(cloneRes.right().value());
392 if (result == null) {
393 certifiedToscaElement = cloneRes.left().value();
394 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
395 if (status != StorageOperationStatus.OK) {
396 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
399 if (result == null) {
400 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
402 } catch (Exception e) {
403 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
409 * Deletes (marks as deleted) all tosca elements according received name and uuid
412 * @param componentType
413 * @param componentName
417 public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
419 Either<Boolean, StorageOperationStatus> result = null;
420 ToscaElementOperation operation = getToscaElementOperation(componentType);
423 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
424 properties.put(GraphPropertyEnum.UUID, uuid);
425 properties.put(GraphPropertyEnum.NAME, componentName);
426 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
427 if (getToscaElementsRes.isRight()) {
428 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
430 if (result == null) {
431 result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
433 if (result == null) {
434 result = Either.left(true);
436 } catch (Exception e) {
437 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
443 * Performs cancelation or failure of certification for received tosca element
445 * @param toscaElementId
451 public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
452 Either<ToscaElement, StorageOperationStatus> result = null;
453 StorageOperationStatus status;
454 ToscaElementOperation operation = null;
455 GraphVertex toscaElement = null;
456 GraphVertex modifier = null;
458 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
459 if (getVerticesRes.isRight()) {
460 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
461 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
463 if (result == null) {
464 toscaElement = getVerticesRes.left().value().get(toscaElementId);
465 modifier = getVerticesRes.left().value().get(modifierId);
466 operation = getToscaElementOperation(toscaElement.getLabel());
467 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
468 toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
469 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
471 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
472 if (updateVertexRes.isRight()) {
473 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
474 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
477 if (result == null) {
478 // cancel certification process
479 status = handleRelationsUponCancelCertification(toscaElement, nextState);
480 if (status != StorageOperationStatus.OK) {
481 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations upon cancel certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
484 if (result == null) {
485 // fail certification
486 status = handleRelationsUponFailCertification(toscaElement, nextState);
487 if (status != StorageOperationStatus.OK) {
488 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations upon fail certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
491 if (result == null) {
492 result = operation.getToscaElement(toscaElementId);
494 } catch (Exception e) {
495 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during cancel or fail certification of tosca element {}. {}. ", toscaElementId, e.getMessage());
500 public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
501 return findUserVertex(userId);
504 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
505 Either<Boolean, StorageOperationStatus> result = Either.left(true);
506 for (GraphVertex resourceToDelete : toscaElements) {
507 if (!((String) resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
508 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
509 if (deleteElementRes.isRight()) {
510 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
511 result = Either.right(deleteElementRes.right().value());
519 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
520 StorageOperationStatus result = null;
521 Edge foundEdge = null;
522 Iterator<Edge> certReqUserEdgeIter = null;
523 // add rfc relation to preserve follower information
524 // get user of certification request
525 certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
526 if (certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()) {
527 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
528 result = StorageOperationStatus.NOT_FOUND;
530 if (result == null) {
531 TitanOperationStatus createVersionEdgeStatus = titanDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
532 if (createVersionEdgeStatus != TitanOperationStatus.OK) {
533 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
534 createVersionEdgeStatus);
535 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createVersionEdgeStatus);
538 if (result == null) {
539 if (certReqUserEdgeIter!=null) {
540 while (certReqUserEdgeIter.hasNext()) {
541 Edge edge = certReqUserEdgeIter.next();
542 if (((String) titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name())) {
549 if (foundEdge == null) {
550 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
551 result = StorageOperationStatus.NOT_FOUND;
554 if (result == null) {
555 TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
556 if (createEdgeRes != TitanOperationStatus.OK) {
557 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
558 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
561 if (result == null) {
562 result = StorageOperationStatus.OK;
567 private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
568 StorageOperationStatus result = null;
569 TitanOperationStatus status = null;
572 if (nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) {
573 // fail certification
574 // delete relation CERTIFICATION_IN_PROGRESS
575 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
576 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
578 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
579 if (deleteResult.isRight()) {
580 status = deleteResult.right().value();
581 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
582 result = StorageOperationStatus.INCONSISTENCY;
584 if (result == null) {
585 // delete relation READY_FOR_CERTIFICATION
586 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
587 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
588 if (deleteResult.isRight()) {
589 status = deleteResult.right().value();
590 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, status);
591 result = StorageOperationStatus.INCONSISTENCY;
594 if (result == null) {
595 // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
596 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
597 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
598 if (deleteResult.isRight()) {
599 status = deleteResult.right().value();
600 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, status);
601 result = StorageOperationStatus.INCONSISTENCY;
604 if (result == null) {
605 // create new STATE relation NOT_CERTIFIED_CHECKIN
606 originEdge = deleteResult.left().value();
607 user = originEdge.outVertex();
608 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
609 if (status != TitanOperationStatus.OK) {
610 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
611 result = StorageOperationStatus.INCONSISTENCY;
614 if (result == null) {
615 // delete relation LAST_MODIFIER (in order to change tester to designer)
616 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
617 if (status != TitanOperationStatus.OK) {
618 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
619 result = StorageOperationStatus.INCONSISTENCY;
622 if (result == null) {
623 // create new LAST_MODIFIER relation
624 originEdge = deleteResult.left().value();
625 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
626 if (status != TitanOperationStatus.OK) {
627 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
628 result = StorageOperationStatus.INCONSISTENCY;
632 if (result == null) {
633 result = StorageOperationStatus.OK;
638 private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
639 StorageOperationStatus result = null;
641 if (nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
642 // delete relation CERTIFICATION_IN_PROGRESS
643 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
644 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
645 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
647 if (deleteResult.isRight()) {
648 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", deleteResult.right().value());
649 result = StorageOperationStatus.INCONSISTENCY;
651 if (result == null) {
652 // delete relation READY_FOR_CERTIFICATION (LAST_STATE)
653 properties.put(GraphPropertyEnum.STATE, nextState);
654 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
656 if (deleteResult.isRight()) {
657 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS, deleteResult.right().value());
658 result = StorageOperationStatus.INCONSISTENCY;
661 if (result == null) {
662 // create relation READY_FOR_CERTIFICATION (STATE)
663 originEdge = deleteResult.left().value();
664 TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
665 if (status != TitanOperationStatus.OK) {
666 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
667 result = StorageOperationStatus.INCONSISTENCY;
670 if (result == null) {
671 result = StorageOperationStatus.OK;
677 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
678 StorageOperationStatus result = null;
679 if (majorVersion > 0) {
680 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
681 if (findRes.isRight()) {
682 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
683 result = findRes.right().value();
685 if (result == null) {
686 Vertex lastCertifiedVertex = findRes.left().value();
687 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
688 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
689 TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
690 if (status != TitanOperationStatus.OK) {
691 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
692 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
694 // remove previous certified version from the catalog
695 GraphVertex lastCertifiedV = new GraphVertex();
696 lastCertifiedV.setVertex((TitanVertex) lastCertifiedVertex);
697 lastCertifiedV.setUniqueId((String) titanDao.getProperty((TitanVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
698 StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
699 if (res != StorageOperationStatus.OK) {
704 if (result == null) {
705 result = StorageOperationStatus.OK;
710 private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
711 TitanOperationStatus status;
712 StorageOperationStatus result = null;
714 if (((String) toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
715 // remove CHECKOUT relation
716 Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
717 if (deleteRes.isRight()) {
718 status = deleteRes.right().value();
719 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
720 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
722 if (result == null) {
723 // create CHECKIN relation
724 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
725 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
726 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
727 if (status != TitanOperationStatus.OK) {
728 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
729 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
733 status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
734 if (status != TitanOperationStatus.OK) {
735 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
738 if (result == null) {
739 // create RFC relation
740 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
741 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
742 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
743 if (status != TitanOperationStatus.OK) {
744 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
745 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
748 if (result == null) {
749 result = StorageOperationStatus.OK;
754 private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
756 StorageOperationStatus result = null;
757 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
758 if (status != TitanOperationStatus.OK) {
759 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
761 if (result == null) {
762 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
763 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
764 status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
765 if (status != TitanOperationStatus.OK) {
766 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
767 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
770 if (result == null) {
771 Either<GraphVertex, StorageOperationStatus> updateRelationsRes = updateLastModifierEdge(toscaElement, owner, modifier);
772 if (updateRelationsRes.isRight()) {
773 result = updateRelationsRes.right().value();
776 if (result == null) {
777 result = StorageOperationStatus.OK;
782 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
783 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
786 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
787 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
788 return Either.left(vertex);
790 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
791 if (!edgeIter.hasNext()) {
792 return Either.right(StorageOperationStatus.NOT_FOUND);
794 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
797 private boolean isCertifiedVersion(String version) {
798 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
799 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
805 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
807 StorageOperationStatus result = StorageOperationStatus.OK;
808 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
809 if (!previousVersion.endsWith(".0")) {
811 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
813 Map<String, Object> propertiesToUpdate = new HashMap<>();
814 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
815 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
816 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
817 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
819 titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
821 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
822 if (!edgesIter.hasNext()) {
823 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
824 result = StorageOperationStatus.NOT_FOUND;
826 Edge lastStateEdge = edgesIter.next();
827 Vertex lastModifier = lastStateEdge.outVertex();
828 TitanOperationStatus replaceRes = titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
829 if (replaceRes != TitanOperationStatus.OK) {
830 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
831 result = StorageOperationStatus.INCONSISTENCY;
832 if (replaceRes != TitanOperationStatus.INVALID_ID) {
833 result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
838 } catch (Exception e) {
839 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
845 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
846 StorageOperationStatus result = null;
847 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
848 String toscaElementId = toscaElementVertex.getUniqueId();
849 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
850 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
851 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
852 if (updateVertexRes.isRight()) {
853 TitanOperationStatus titatStatus = updateVertexRes.right().value();
854 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
855 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
857 Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
858 if (result == null) {
859 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
861 deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
862 if (deleteEdgeRes.isRight()) {
863 TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
864 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
865 if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
866 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
868 result = StorageOperationStatus.INCONSISTENCY;
872 if (result == null) {
873 TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
874 if (createEdgeRes != TitanOperationStatus.OK) {
875 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
879 if (result == null) {
880 result = StorageOperationStatus.OK;
885 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
887 Either<ToscaElement, StorageOperationStatus> result = null;
888 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
889 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
890 // check if component with the next version doesn't exist.
891 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
892 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
893 Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
894 String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
895 String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
896 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. ",
897 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
898 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
900 if (result == null) {
901 toscaElementVertex.getOrSetDefaultInstantiationTypeForToscaElementJson();
902 cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
903 if (cloneResult.isRight()) {
904 result = Either.right(cloneResult.right().value());
907 GraphVertex clonedVertex = null;
908 if (result == null) {
909 clonedVertex = cloneResult.left().value();
910 TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
911 if (status != TitanOperationStatus.OK) {
912 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
913 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
914 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
917 if (result == null) {
918 Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
919 GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
920 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
921 if (updateCatalogRes != StorageOperationStatus.OK) {
922 return Either.right(updateCatalogRes);
924 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
925 if (result.isRight()) {
928 ToscaElement toscaElement = result.left().value();
929 if (toscaElement.getToscaType() == ToscaElementTypeEnum.TOPOLOGY_TEMPLATE) {
930 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
937 private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
938 ToscaElement toscaElement) {
939 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
940 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
941 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
942 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
943 Map<String, ToscaElement> origCompMap = new HashMap<>();
944 if (instInputs == null) {
945 instInputs = new HashMap<>();
947 if (instGroups == null) {
948 instGroups = new HashMap<>();
950 if (instArtifactsMap == null) {
951 instArtifactsMap = new HashMap<>();
953 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
954 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
955 boolean needUpdateComposition = false;
957 if (instancesMap != null && !instancesMap.isEmpty()) {
958 for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
959 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
960 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
961 collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
963 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
964 if (needUpdateComposition) {
965 instancesMap.put(vfInst.getUniqueId(), vfInst);
968 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add to graph instInputs {} instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
969 if (!instInputs.isEmpty()) {
970 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
971 GraphVertex toscaDataVertex = null;
972 Either<GraphVertex, TitanOperationStatus> instInpVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
973 if (instInpVertexEither.isLeft()) {
974 toscaDataVertex = instInpVertexEither.left().value();
977 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
978 if (status != StorageOperationStatus.OK) {
979 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
980 result = Either.right(status);
985 if (!instGroups.isEmpty()) {
986 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
987 GraphVertex toscaDataVertex = null;
988 Either<GraphVertex, TitanOperationStatus> instGrVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
989 if (instGrVertexEither.isLeft()) {
990 toscaDataVertex = instGrVertexEither.left().value();
993 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
994 if (status != StorageOperationStatus.OK) {
995 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
996 result = Either.right(status);
1001 if (needUpdateComposition) {
1002 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before update Instances ");
1003 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
1004 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1005 compositionDataDefinition.setComponentInstances(instancesMap);
1006 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(clonedVertex);
1007 if (updateElement.isRight()) {
1008 TitanOperationStatus status = updateElement.right().value();
1009 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
1010 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
1015 result = operation.getToscaElement(clonedVertex.getUniqueId());
1018 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
1023 // TODO remove after jsonModelMigration
1024 public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
1025 return fixToscaComponentName(vfInst, origCompMap);
1028 private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
1029 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
1030 String ciUid = vfInst.getUniqueId();
1031 String origCompUid = vfInst.getComponentUid();
1032 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
1033 ToscaElement origComp = null;
1034 if (!origCompMap.containsKey(origCompUid)) {
1035 Either<ToscaElement, StorageOperationStatus> origCompEither;
1036 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
1037 origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1039 origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
1041 if (origCompEither.isRight()) {
1042 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1045 origComp = origCompEither.left().value();
1046 origCompMap.put(origCompUid, origComp);
1048 origComp = origCompMap.get(origCompUid);
1050 String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
1051 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
1052 vfInst.setToscaComponentName(toscaName);
1058 private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
1059 boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
1060 String ciUid = vfInst.getUniqueId();
1061 String origCompUid = vfInst.getComponentUid();
1062 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
1063 TopologyTemplate origComp = null;
1064 if (!origCompMap.containsKey(origCompUid)) {
1065 Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1066 if (origCompEither.isRight()) {
1067 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1070 origComp = (TopologyTemplate) origCompEither.left().value();
1071 origCompMap.put(origCompUid, origComp);
1073 origComp = (TopologyTemplate) origCompMap.get(origCompUid);
1075 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
1077 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
1078 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
1079 if (origInputs != null) {
1080 if (!instInputs.containsKey(ciUid)) {
1081 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
1082 instInputs.put(ciUid, instProperties);
1085 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
1086 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
1087 origInputs.forEach((propName, propMap) -> {
1088 if (!instProp.containsKey(propName)) {
1089 instProp.put(propName, propMap);
1093 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
1096 if (isAddInstGroup) {
1097 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before create group instance. ");
1098 List<GroupDataDefinition> filteredGroups = null;
1100 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1101 if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
1102 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
1103 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1105 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1106 if (CollectionUtils.isNotEmpty(filteredGroups)) {
1107 MapArtifactDataDefinition instArifacts = null;
1108 if (!instArtifactsMap.containsKey(ciUid)) {
1110 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "istance artifacts not found ");
1112 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
1114 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
1115 addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
1117 instArtifactsMap.put(ciUid, instArifacts);
1120 instArifacts = instArtifactsMap.get(ciUid);
1123 if (instArifacts != null) {
1124 Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
1126 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
1127 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
1128 for (GroupDataDefinition group : filteredGroups) {
1129 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "create new groupInstance {} ", group.getName());
1130 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
1131 List<String> artifactsUid = new ArrayList<>();
1132 List<String> artifactsId = new ArrayList<>();
1133 if (instDeplArtifMap!=null) {
1134 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
1135 Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
1136 if (op.isPresent()) {
1137 artifactsUid.add(artifact.getArtifactUUID());
1138 artifactsId.add(artifact.getUniqueId());
1143 groupInstance.setGroupInstanceArtifacts(artifactsId);
1144 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
1145 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
1147 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
1148 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
1156 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
1157 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1158 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
1159 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1160 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1161 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1162 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1163 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1165 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1166 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1167 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
1168 if (isFirstCheckoutAfterCertification(nextVersion)) {
1169 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
1171 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
1172 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
1173 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1175 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
1176 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
1178 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1179 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
1180 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1182 long currTime = System.currentTimeMillis();
1183 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
1184 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
1185 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1186 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1187 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
1188 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
1191 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1192 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1194 return nextVersionToscaElementVertex;
1197 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1198 Either<GraphVertex, StorageOperationStatus> result;
1199 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
1200 GraphVertex clonedToscaElement = null;
1201 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
1202 if (result.isRight()) {
1203 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
1205 clonedToscaElement = result.left().value();
1206 StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
1207 if (updateEdgeToCatalog != StorageOperationStatus.OK) {
1208 return Either.right(updateEdgeToCatalog);
1210 deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
1211 if (deleteResult.isRight()) {
1212 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
1213 result = Either.right(deleteResult.right().value());
1216 if (result.isLeft()) {
1217 result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
1222 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
1223 Either<GraphVertex, StorageOperationStatus> result = null;
1224 Vertex previousCertifiedToscaElement = null;
1225 if (majorVersion > 0) {
1226 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
1228 if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
1229 result = Either.right(StorageOperationStatus.NOT_FOUND);
1231 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
1232 if (previousCertifiedToscaElement == null) {
1233 result = Either.right(StorageOperationStatus.NOT_FOUND);
1236 if (result == null) {
1237 TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
1238 if (status != TitanOperationStatus.OK) {
1239 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
1240 previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
1241 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
1246 if (result == null) {
1247 result = Either.left(clonedToscaElement);
1252 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
1254 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
1255 if (edges.hasNext()) {
1256 return edges.next().outVertex();
1261 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
1262 Either<List<GraphVertex>, StorageOperationStatus> result = null;
1264 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
1265 List<GraphVertex> previosVersions = null;
1266 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
1267 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
1269 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
1270 properties.put(GraphPropertyEnum.UUID, uuid);
1271 properties.put(GraphPropertyEnum.NAME, componentName);
1272 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
1273 if (getToscaElementsRes.isRight()) {
1274 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
1276 if (result == null) {
1277 previosVersions = getToscaElementsRes.left().value();
1278 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
1279 if (deleteResult.isRight()) {
1280 result = Either.right(deleteResult.right().value());
1283 if (result == null) {
1284 result = Either.left(previosVersions);
1286 } catch (Exception e) {
1287 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
1292 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1294 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1295 String uniqueId = IdBuilderUtils.generateUniqueId();
1296 Map<GraphPropertyEnum, Object> metadataProperties = new EnumMap<>(toscaElementVertex.getMetadataProperties());
1297 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1298 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1299 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1300 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1302 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1303 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1304 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMITER + "0");
1305 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1306 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1307 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
1308 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
1309 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1310 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1312 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
1313 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
1315 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1316 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
1317 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1319 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1320 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1322 return nextVersionToscaElementVertex;
1326 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
1327 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
1328 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
1329 if (result.isLeft()) {
1330 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
1331 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1332 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
1334 if (result.isLeft()) {
1335 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
1336 if (updateRelationsRes.isRight()) {
1337 result = Either.right(updateRelationsRes.right().value());
1343 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
1345 Either<GraphVertex, StorageOperationStatus> result;
1347 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
1348 if (updateVertexRes.isRight()) {
1349 TitanOperationStatus titatStatus = updateVertexRes.right().value();
1350 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
1351 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
1353 result = Either.left(updateVertexRes.left().value());
1358 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1359 Either<GraphVertex, StorageOperationStatus> result = null;
1360 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
1361 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
1363 if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
1364 // In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
1365 Map<GraphPropertyEnum, Object> vertexProperties = new EnumMap<>(GraphPropertyEnum.class);
1366 vertexProperties.put(GraphPropertyEnum.STATE, nextState);
1367 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
1368 if (deleteResult.isRight()) {
1369 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
1370 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to update last state relation");
1371 result = Either.right(StorageOperationStatus.INCONSISTENCY);
1374 if (result == null) {
1375 // Remove CHECKOUT relation
1376 Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
1377 if (deleteEdgeResult.isRight()) {
1378 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1379 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
1382 if (result == null) {
1383 // Create CHECKIN relation
1384 Map<EdgePropertyEnum, Object> edgeProperties = new EnumMap<>(EdgePropertyEnum.class);
1385 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1386 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1387 if (createEdgeRes != TitanOperationStatus.OK) {
1388 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1389 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1392 if (result == null) {
1393 result = Either.left(toscaElementVertex);
1398 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1399 Either<GraphVertex, StorageOperationStatus> result = null;
1400 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
1401 Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1402 if (deleteEdgeRes.isRight()) {
1403 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1404 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
1406 if (result == null) {
1407 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1409 if (createEdgeRes != TitanOperationStatus.OK) {
1410 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1411 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1413 result = Either.left(modifierVertex);
1417 result = Either.left(ownerVertex);
1422 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1423 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1424 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1425 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1426 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1427 return verticesToGetParameters;
1430 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1431 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1432 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1433 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1434 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1435 return verticesToGetParameters;
1438 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1439 //Implementation is currently identical
1440 return prepareParametersToGetVerticesForRequestCertification(toscaElementId,modifierId, ownerId);
1443 private String getNextCertifiedVersion(String version) {
1444 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1445 Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
1446 return nextMajorVersion + VERSION_DELIMITER + "0";
1449 private String getNextVersion(String currVersion) {
1450 String[] versionParts = currVersion.split(VERSION_DELIMITER_REGEXP);
1451 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1452 return versionParts[0] + VERSION_DELIMITER + minorVersion;
1455 private Integer getMinorVersion(String version) {
1456 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1457 return Integer.parseInt(versionParts[1]);
1460 private Integer getMajorVersion(String version) {
1461 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1462 return Integer.parseInt(versionParts[0]);
1465 private boolean isFirstCheckoutAfterCertification(String version) {
1466 return (Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[1]) == 1);
1469 public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
1470 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
1471 Either<ToscaElement, StorageOperationStatus> result = null;
1472 GraphVertex toscaElement = null;
1473 GraphVertex modifier = null;
1476 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
1477 if (getVerticesRes.isRight()) {
1478 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
1479 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
1481 if (result == null) {
1482 toscaElement = getVerticesRes.left().value().get(toscaElementId);
1483 modifier = getVerticesRes.left().value().get(modifierId);
1484 owner = getVerticesRes.left().value().get(ownerId);
1486 StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
1487 if (status != StorageOperationStatus.OK) {
1488 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
1491 if (result == null) {
1492 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
1494 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1495 toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
1497 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
1498 if (resultUpdate.isRight()) {
1499 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
1500 result = Either.right(resultUpdate.right().value());
1503 if (result == null) {
1504 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
1505 result = operation.getToscaElement(toscaElement.getUniqueId());
1509 } catch (Exception e) {
1510 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
1515 private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
1517 StorageOperationStatus result = null;
1518 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
1519 if (status != TitanOperationStatus.OK) {
1520 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1522 if (result == null) {
1523 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
1524 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
1525 status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
1526 if (status != TitanOperationStatus.OK) {
1527 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
1528 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1531 if (result == null) {
1532 result = StorageOperationStatus.OK;
1537 private StorageOperationStatus updateEdgeToCatalogRootByUndoCheckout(TitanVertex preV, GraphVertex curV) {
1539 return updateEdgeToCatalogRoot(null, curV);
1541 String uniqueIdPreVer = (String) titanDao.getProperty((TitanVertex) preV, GraphPropertyEnum.UNIQUE_ID.getProperty());
1542 LifecycleStateEnum state = LifecycleStateEnum.findState((String) titanDao.getProperty(preV, GraphPropertyEnum.STATE.getProperty()));
1543 if (state == LifecycleStateEnum.CERTIFIED) {
1544 return updateEdgeToCatalogRoot(null, curV);
1546 return titanDao.getVertexById(uniqueIdPreVer)
1547 .either(l -> updateEdgeToCatalogRoot(l, curV),
1548 DaoStatusConverter::convertTitanStatusToStorageStatus);
1551 private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
1552 Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
1553 if (catalog.isRight()) {
1554 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
1555 return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
1557 GraphVertex catalogV = catalog.left().value();
1558 if (newVersionV != null) {
1559 Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1561 if ( isAbstract == null || !isAbstract ) {
1562 // no new vertex, only delete previous
1563 TitanOperationStatus result = titanDao.createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
1564 if (result != TitanOperationStatus.OK) {
1565 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
1566 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
1570 if (prevVersionV != null) {
1571 Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1572 if (isAbstract == null || !isAbstract) {
1573 // if prev == null -> new resource was added
1574 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
1575 if (deleteResult.isRight()) {
1576 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
1577 return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteResult.right().value());
1581 return StorageOperationStatus.OK;