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 java.util.ArrayList;
24 import java.util.EnumMap;
25 import java.util.HashMap;
26 import java.util.Iterator;
27 import java.util.List;
29 import java.util.Optional;
30 import java.util.stream.Collectors;
32 import org.apache.commons.collections.CollectionUtils;
33 import org.apache.commons.collections.MapUtils;
34 import org.apache.commons.lang.StringUtils;
35 import org.apache.commons.lang3.tuple.ImmutablePair;
36 import org.apache.tinkerpop.gremlin.structure.Direction;
37 import org.apache.tinkerpop.gremlin.structure.Edge;
38 import org.apache.tinkerpop.gremlin.structure.Vertex;
39 import org.openecomp.sdc.be.config.ConfigurationManager;
40 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
41 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
42 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
43 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
44 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
45 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
46 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
47 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
48 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
49 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
50 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
51 import org.openecomp.sdc.be.datatypes.elements.CompositionDataDefinition;
52 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
53 import org.openecomp.sdc.be.datatypes.elements.GroupInstanceDataDefinition;
54 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
55 import org.openecomp.sdc.be.datatypes.elements.MapGroupsDataDefinition;
56 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
57 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
58 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
59 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
60 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
61 import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum;
62 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
63 import org.openecomp.sdc.be.model.ComponentParametersView;
64 import org.openecomp.sdc.be.model.DistributionStatusEnum;
65 import org.openecomp.sdc.be.model.LifecycleStateEnum;
66 import org.openecomp.sdc.be.model.User;
67 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
68 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
69 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
70 import org.openecomp.sdc.be.model.jsontitan.enums.JsonConstantKeysEnum;
71 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
72 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
73 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
74 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
75 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
76 import org.slf4j.Logger;
77 import org.slf4j.LoggerFactory;
79 import com.thinkaurelius.titan.core.TitanVertex;
81 import fj.data.Either;
83 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
86 * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
88 public class ToscaElementLifecycleOperation extends BaseOperation {
90 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
91 public static final String VERSION_DELIMETER = ".";
92 public static final String VERSION_DELIMETER_REGEXP = "\\.";
94 private static Logger logger = LoggerFactory.getLogger(ToscaElementLifecycleOperation.class.getName());
97 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
100 * @param toscaElementId
105 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
106 Either<GraphVertex, StorageOperationStatus> updateResult = null;
107 Either<ToscaElement, StorageOperationStatus> result = null;
108 Map<String, GraphVertex> vertices = null;
109 ToscaElementOperation operation;
111 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckin(toscaElementId, modifierId, ownerId));
112 if (getVerticesRes.isRight()) {
113 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
114 updateResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
116 vertices = getVerticesRes.left().value();
117 updateResult = checkinToscaELement(currState, vertices.get(toscaElementId), vertices.get(ownerId), vertices.get(modifierId), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
119 if (updateResult.isLeft()) {
120 ComponentParametersView componentParametersView = buildComponentParametersViewAfterCheckin();
121 operation = getToscaElementOperation(vertices.get(toscaElementId).getLabel());
122 result = operation.getToscaElement(updateResult.left().value().getUniqueId(), componentParametersView);
123 if (result.isRight()) {
124 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to get updated tosca element {}. Status is {}", toscaElementId, result.right().value());
127 result = Either.right(updateResult.right().value());
129 } catch (Exception e) {
130 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkin of tosca element {}. {} ", toscaElementId, e.getMessage());
136 * Returns vertex presenting owner of tosca element specified by uniqueId
138 * @param toscaElement
141 public Either<User, StorageOperationStatus> getToscaElementOwner(String toscaElementId) {
142 Either<User, StorageOperationStatus> result = null;
143 GraphVertex toscaElement = null;
144 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
145 if (getToscaElementRes.isRight()) {
146 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
148 if (result == null) {
149 toscaElement = getToscaElementRes.left().value();
150 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
151 if (vertices == null || !vertices.hasNext()) {
152 result = Either.right(StorageOperationStatus.NOT_FOUND);
154 result = Either.left(convertToUser(vertices.next()));
161 * Returns vertex presenting owner of tosca element specified by uniqueId
163 * @param toscaElement
166 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
167 Either<User, StorageOperationStatus> result = null;
168 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
169 if (vertices == null || !vertices.hasNext()) {
170 result = Either.right(StorageOperationStatus.NOT_FOUND);
172 result = Either.left(convertToUser(vertices.next()));
178 * Performs checkout of a tosca element
180 * @param toscaElementId
186 public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
187 Either<ToscaElement, StorageOperationStatus> result = null;
188 Map<String, GraphVertex> vertices = null;
190 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
191 if (getVerticesRes.isRight()) {
192 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
193 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
195 if (result == null) {
196 vertices = getVerticesRes.left().value();
197 // update previous component if not certified
198 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
199 if (status != StorageOperationStatus.OK) {
200 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
201 result = Either.right(status);
204 if (result == null) {
205 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
206 if (result.isRight()) {
207 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
211 } catch (Exception e) {
212 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
218 * Performs undo checkout for tosca element
220 * @param toscaElementId
223 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
224 Either<ToscaElement, StorageOperationStatus> result = null;
225 Either<GraphVertex, TitanOperationStatus> getToscaElementRes = null;
226 Iterator<Edge> nextVersionComponentIter = null;
227 ToscaElementOperation operation;
228 Vertex preVersionVertex = null;
230 getToscaElementRes = titanDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
231 if (getToscaElementRes.isRight()) {
232 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
233 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementRes.right().value()));
235 GraphVertex currVersionV = getToscaElementRes.left().value();
236 if (result == null && hasPreviousVersion(currVersionV)) {
237 // find previous version
238 nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
239 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
240 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
241 result = Either.right(StorageOperationStatus.NOT_FOUND);
243 if (result == null) {
244 preVersionVertex = nextVersionComponentIter.next().outVertex();
245 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
246 if (updateOldResourceResult != StorageOperationStatus.OK) {
247 result = Either.right(updateOldResourceResult);
251 if (result == null) {
252 GraphVertex prevVersionV = null;
253 if (preVersionVertex != null) {
254 prevVersionV = new GraphVertex();
255 prevVersionV.setVertex((TitanVertex) preVersionVertex);
256 String uniqueIdPreVer = (String) titanDao.getProperty((TitanVertex) preVersionVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
257 prevVersionV.setUniqueId(uniqueIdPreVer);
259 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(prevVersionV, currVersionV);
260 if (updateCatalogRes != StorageOperationStatus.OK) {
261 return Either.right(updateCatalogRes);
263 operation = getToscaElementOperation(currVersionV.getLabel());
264 result = operation.deleteToscaElement(currVersionV);
266 } catch (Exception e) {
267 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
272 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
273 boolean hasPreviousVersion = true;
274 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
275 if (StringUtils.isEmpty(version) || version.equals("0.1"))
276 hasPreviousVersion = false;
277 return hasPreviousVersion;
281 * Performs request certification for tosca element
283 * @param toscaElementId
288 public Either<ToscaElement, StorageOperationStatus> requestCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
289 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
290 Either<ToscaElement, StorageOperationStatus> result = null;
291 GraphVertex toscaElement = null;
292 GraphVertex modifier = null;
295 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
296 if (getVerticesRes.isRight()) {
297 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
298 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
300 if (result == null) {
301 toscaElement = getVerticesRes.left().value().get(toscaElementId);
302 modifier = getVerticesRes.left().value().get(modifierId);
303 owner = getVerticesRes.left().value().get(ownerId);
305 StorageOperationStatus status = handleRelationsUponRequestForCertification(toscaElement, modifier, owner);
306 if (status != StorageOperationStatus.OK) {
307 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
310 if (result == null) {
311 LifecycleStateEnum nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION;
313 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
314 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
316 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
317 if (resultUpdate.isRight()) {
318 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
319 result = Either.right(resultUpdate.right().value());
322 if (result == null) {
323 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
324 result = operation.getToscaElement(toscaElement.getUniqueId());
328 } catch (Exception e) {
329 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
335 * Starts certification of tosca element
337 * @param toscaElementId
342 public Either<ToscaElement, StorageOperationStatus> startCertificationToscaElement(String toscaElementId, String modifierId, String ownerId) {
343 Either<ToscaElement, StorageOperationStatus> result = null;
344 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
345 GraphVertex toscaElement = null;
346 GraphVertex modifier = null;
349 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
350 if (getVerticesRes.isRight()) {
351 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
352 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
354 if (result == null) {
355 toscaElement = getVerticesRes.left().value().get(toscaElementId);
356 modifier = getVerticesRes.left().value().get(modifierId);
357 owner = getVerticesRes.left().value().get(ownerId);
359 StorageOperationStatus status = handleRelationsUponCertification(toscaElement, modifier, owner);
360 if (status != StorageOperationStatus.OK) {
361 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations during certification of tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
364 if (result == null) {
365 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS;
367 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
368 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
370 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
371 if (resultUpdate.isRight()) {
372 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Couldn't set lifecycle for component {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
373 result = Either.right(resultUpdate.right().value());
376 if (result == null) {
377 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
378 result = operation.getToscaElement(toscaElement.getUniqueId());
380 } catch (Exception e) {
381 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during start certification tosca element {}. {}", toscaElementId, e.getMessage());
386 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
387 Either<ToscaElement, StorageOperationStatus> result = null;
388 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
389 GraphVertex toscaElement = null;
390 GraphVertex modifier = null;
391 GraphVertex certifiedToscaElement = null;
392 Integer majorVersion = null;
394 StorageOperationStatus status;
396 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
397 if (getVerticesRes.isRight()) {
398 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
399 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
401 if (result == null) {
402 toscaElement = getVerticesRes.left().value().get(toscaElementId);
403 modifier = getVerticesRes.left().value().get(modifierId);
404 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
405 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
406 if (status != StorageOperationStatus.OK) {
407 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
410 if (result == null) {
411 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
412 if (cloneRes.isRight()) {
413 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
414 result = Either.right(cloneRes.right().value());
417 if (result == null) {
418 certifiedToscaElement = cloneRes.left().value();
419 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
420 if (status != StorageOperationStatus.OK) {
421 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
424 if (result == null) {
425 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
427 } catch (Exception e) {
428 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
434 * Deletes (marks as deleted) all tosca elements according received name and uuid
437 * @param componentType
438 * @param componentName
442 public Either<Boolean, StorageOperationStatus> deleteOldToscaElementVersions(VertexTypeEnum vertexType, ComponentTypeEnum componentType, String componentName, String uuid) {
444 Either<Boolean, StorageOperationStatus> result = null;
445 ToscaElementOperation operation = getToscaElementOperation(componentType);
448 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
449 properties.put(GraphPropertyEnum.UUID, uuid);
450 properties.put(GraphPropertyEnum.NAME, componentName);
451 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(vertexType, properties, JsonParseFlagEnum.ParseMetadata);
452 if (getToscaElementsRes.isRight()) {
453 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
455 if (result == null) {
456 result = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
458 if (result == null) {
459 result = Either.left(true);
461 } catch (Exception e) {
462 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
468 * Performs cancelation or failure of certification for received tosca element
470 * @param toscaElementId
476 public Either<ToscaElement, StorageOperationStatus> cancelOrFailCertification(String toscaElementId, String modifierId, String ownerId, LifecycleStateEnum nextState) {
477 Either<ToscaElement, StorageOperationStatus> result = null;
478 StorageOperationStatus status;
479 ToscaElementOperation operation = null;
480 GraphVertex toscaElement = null;
481 GraphVertex modifier = null;
483 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
484 if (getVerticesRes.isRight()) {
485 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
486 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
488 if (result == null) {
489 toscaElement = getVerticesRes.left().value().get(toscaElementId);
490 modifier = getVerticesRes.left().value().get(modifierId);
491 operation = getToscaElementOperation(toscaElement.getLabel());
492 toscaElement.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
493 toscaElement.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifier.getUniqueId());
494 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
496 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElement);
497 if (updateVertexRes.isRight()) {
498 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update vertex {} . Status is {}. ", toscaElementId, updateVertexRes.right().value());
499 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateVertexRes.right().value()));
502 if (result == null) {
503 // cancel certification process
504 status = handleRelationsUponCancelCertification(toscaElement, nextState);
505 if (status != StorageOperationStatus.OK) {
506 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon cancel certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
509 if (result == null) {
510 // fail certification
511 status = handleRelationsUponFailCertification(toscaElement, nextState);
512 if (status != StorageOperationStatus.OK) {
513 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations upon fail certification {}. Status is {}. ", toscaElement.getUniqueId(), status);
516 if (result == null) {
517 result = operation.getToscaElement(toscaElementId);
519 } catch (Exception e) {
520 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during cancel or fail certification of tosca element {}. {}. ", toscaElementId, e.getMessage());
525 public Either<GraphVertex, TitanOperationStatus> findUser(String userId) {
526 return findUserVertex(userId);
529 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
530 Either<Boolean, StorageOperationStatus> result = Either.left(true);
531 for (GraphVertex resourceToDelete : toscaElements) {
532 if (!((String) resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
533 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
534 if (deleteElementRes.isRight()) {
535 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
536 result = Either.right(deleteElementRes.right().value());
544 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
545 StorageOperationStatus result = null;
546 Edge foundEdge = null;
547 Iterator<Edge> certReqUserEdgeIter = null;
548 // add rfc relation to preserve follower information
549 // get user of certification request
550 certReqUserEdgeIter = toscaElement.getVertex().edges(Direction.IN, GraphEdgeLabels.LAST_STATE.name());
551 if (certReqUserEdgeIter == null || !certReqUserEdgeIter.hasNext()) {
552 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
553 result = StorageOperationStatus.NOT_FOUND;
555 if (result == null) {
556 TitanOperationStatus createVersionEdgeStatus = titanDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
557 if (createVersionEdgeStatus != TitanOperationStatus.OK) {
558 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
559 createVersionEdgeStatus);
560 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createVersionEdgeStatus);
563 if (result == null) {
565 while (certReqUserEdgeIter.hasNext()) {
566 Edge edge = certReqUserEdgeIter.next();
567 if (((String) titanDao.getProperty(edge, EdgePropertyEnum.STATE)).equals(LifecycleStateEnum.READY_FOR_CERTIFICATION.name())) {
573 if (foundEdge == null) {
574 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find rfc relation during certification clone. ");
575 result = StorageOperationStatus.NOT_FOUND;
578 if (result == null) {
579 TitanOperationStatus createEdgeRes = titanDao.createEdge(foundEdge.outVertex(), certifiedToscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, foundEdge);
580 if (createEdgeRes != TitanOperationStatus.OK) {
581 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create rfc relation for component {}. status=", certifiedToscaElement.getUniqueId(), createEdgeRes);
582 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
585 if (result == null) {
586 result = StorageOperationStatus.OK;
591 private StorageOperationStatus handleRelationsUponFailCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
592 StorageOperationStatus result = null;
593 TitanOperationStatus status = null;
596 if (nextState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) {
597 // fail certification
598 // delete relation CERTIFICATION_IN_PROGRESS
599 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
600 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
602 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
603 if (deleteResult.isRight()) {
604 status = deleteResult.right().value();
605 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", status);
606 result = StorageOperationStatus.INCONSISTENCY;
608 if (result == null) {
609 // delete relation READY_FOR_CERTIFICATION
610 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
611 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
612 if (deleteResult.isRight()) {
613 status = deleteResult.right().value();
614 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
615 result = StorageOperationStatus.INCONSISTENCY;
618 if (result == null) {
619 // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE)
620 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
621 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
622 if (deleteResult.isRight()) {
623 status = deleteResult.right().value();
624 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", status);
625 result = StorageOperationStatus.INCONSISTENCY;
628 if (result == null) {
629 // create new STATE relation NOT_CERTIFIED_CHECKIN
630 originEdge = deleteResult.left().value();
631 user = originEdge.outVertex();
632 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
633 if (status != TitanOperationStatus.OK) {
634 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
635 result = StorageOperationStatus.INCONSISTENCY;
638 if (result == null) {
639 // delete relation LAST_MODIFIER (in order to change tester to designer)
640 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
641 if (status != TitanOperationStatus.OK) {
642 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
643 result = StorageOperationStatus.INCONSISTENCY;
646 if (result == null) {
647 // create new LAST_MODIFIER relation
648 originEdge = deleteResult.left().value();
649 status = titanDao.createEdge(user, toscaElement.getVertex(), EdgeLabelEnum.LAST_MODIFIER, originEdge);
650 if (status != TitanOperationStatus.OK) {
651 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create last modifier edge. Status is {}. ", status);
652 result = StorageOperationStatus.INCONSISTENCY;
656 if (result == null) {
657 result = StorageOperationStatus.OK;
662 private StorageOperationStatus handleRelationsUponCancelCertification(GraphVertex toscaElement, LifecycleStateEnum nextState) {
663 StorageOperationStatus result = null;
665 if (nextState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
666 // delete relation CERTIFICATION_IN_PROGRESS
667 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
668 properties.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
669 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.STATE, properties);
671 if (deleteResult.isRight()) {
672 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete state edge. Status is {}. ", deleteResult.right().value());
673 result = StorageOperationStatus.INCONSISTENCY;
675 if (result == null) {
676 // delete relation READY_FOR_CERTIFICATION (LAST_STATE)
677 properties.put(GraphPropertyEnum.STATE, nextState);
678 deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElement, EdgeLabelEnum.LAST_STATE, properties);
680 if (deleteResult.isRight()) {
681 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last state edge. Status is {}. ", deleteResult.right().value());
682 result = StorageOperationStatus.INCONSISTENCY;
685 if (result == null) {
686 // create relation READY_FOR_CERTIFICATION (STATE)
687 originEdge = deleteResult.left().value();
688 TitanOperationStatus status = titanDao.createEdge(originEdge.outVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, originEdge);
689 if (status != TitanOperationStatus.OK) {
690 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create state edge. Status is {}. ", status);
691 result = StorageOperationStatus.INCONSISTENCY;
694 if (result == null) {
695 result = StorageOperationStatus.OK;
701 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
702 StorageOperationStatus result = null;
703 if (majorVersion > 0) {
704 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
705 if (findRes.isRight()) {
706 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
707 result = findRes.right().value();
709 if (result == null) {
710 Vertex lastCertifiedVertex = findRes.left().value();
711 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
712 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
713 TitanOperationStatus status = titanDao.updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
714 if (status != TitanOperationStatus.OK) {
715 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set highest version of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
716 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
718 // remove previous certified version from the catalog
719 GraphVertex lastCertifiedV = new GraphVertex();
720 lastCertifiedV.setVertex((TitanVertex) lastCertifiedVertex);
721 lastCertifiedV.setUniqueId((String) titanDao.getProperty((TitanVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
722 StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
723 if (res != StorageOperationStatus.OK) {
728 if (result == null) {
729 result = StorageOperationStatus.OK;
734 private StorageOperationStatus handleRelationsUponRequestForCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
735 TitanOperationStatus status;
736 StorageOperationStatus result = null;
738 if (((String) toscaElement.getMetadataProperty(GraphPropertyEnum.STATE)).equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) {
739 // remove CHECKOUT relation
740 Either<Edge, TitanOperationStatus> deleteRes = titanDao.deleteEdge(owner, toscaElement, EdgeLabelEnum.STATE);
741 if (deleteRes.isRight()) {
742 status = deleteRes.right().value();
743 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge. Status is {}. ", status);
744 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
746 if (result == null) {
747 // create CHECKIN relation
748 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
749 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN);
750 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.LAST_STATE, properties);
751 if (status != TitanOperationStatus.OK) {
752 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
753 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
757 status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
758 if (status != TitanOperationStatus.OK) {
759 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
762 if (result == null) {
763 // create RFC relation
764 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
765 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.READY_FOR_CERTIFICATION);
766 status = titanDao.createEdge(modifier.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, properties);
767 if (status != TitanOperationStatus.OK) {
768 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge. Status is {}", status);
769 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
772 if (result == null) {
773 result = StorageOperationStatus.OK;
778 private StorageOperationStatus handleRelationsUponCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
780 StorageOperationStatus result = null;
781 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
782 if (status != TitanOperationStatus.OK) {
783 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
785 if (result == null) {
786 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
787 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFICATION_IN_PROGRESS);
788 status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
789 if (status != TitanOperationStatus.OK) {
790 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
791 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
794 if (result == null) {
795 Either<GraphVertex, StorageOperationStatus> updateRelationsRes = updateLastModifierEdge(toscaElement, owner, modifier);
796 if (updateRelationsRes.isRight()) {
797 result = updateRelationsRes.right().value();
800 if (result == null) {
801 result = StorageOperationStatus.OK;
806 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
807 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
810 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
811 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
812 return Either.left(vertex);
814 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
815 if (!edgeIter.hasNext()) {
816 return Either.right(StorageOperationStatus.NOT_FOUND);
818 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
821 private boolean isCertifiedVersion(String version) {
822 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
823 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
829 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
831 StorageOperationStatus result = StorageOperationStatus.OK;
832 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
833 if (!previousVersion.endsWith(".0")) {
835 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
837 Map<String, Object> propertiesToUpdate = new HashMap<>();
838 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
839 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
840 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
841 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
843 titanDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
845 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
846 if (!edgesIter.hasNext()) {
847 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
848 result = StorageOperationStatus.NOT_FOUND;
850 Edge lastStateEdge = edgesIter.next();
851 Vertex lastModifier = lastStateEdge.outVertex();
852 TitanOperationStatus replaceRes = titanDao.replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
853 if (replaceRes != TitanOperationStatus.OK) {
854 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
855 result = StorageOperationStatus.INCONSISTENCY;
856 if (replaceRes != TitanOperationStatus.INVALID_ID) {
857 result = DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRes);
862 } catch (Exception e) {
863 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
869 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
870 StorageOperationStatus result = null;
871 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
872 String toscaElementId = toscaElementVertex.getUniqueId();
873 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
874 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
875 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
876 if (updateVertexRes.isRight()) {
877 TitanOperationStatus titatStatus = updateVertexRes.right().value();
878 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
879 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
881 Either<Edge, TitanOperationStatus> deleteEdgeRes = null;
882 if (result == null) {
883 CommonUtility.addRecordToLog(logger, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
885 deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
886 if (deleteEdgeRes.isRight()) {
887 TitanOperationStatus titanStatus = deleteEdgeRes.right().value();
888 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, titanStatus);
889 if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) {
890 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus);
892 result = StorageOperationStatus.INCONSISTENCY;
896 if (result == null) {
897 TitanOperationStatus createEdgeRes = titanDao.createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
898 if (createEdgeRes != TitanOperationStatus.OK) {
899 result = DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes);
903 if (result == null) {
904 result = StorageOperationStatus.OK;
909 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
911 Either<ToscaElement, StorageOperationStatus> result = null;
912 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
913 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
914 // check if component with the next version doesn't exist.
915 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
916 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
917 Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
918 String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
919 String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
920 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to checkout component {} with version {}. The component with name {} and version {} was fetched from graph as existing following version. ",
921 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
922 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
924 if (result == null) {
925 cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
926 if (cloneResult.isRight()) {
927 result = Either.right(cloneResult.right().value());
930 GraphVertex clonedVertex = null;
931 if (result == null) {
932 clonedVertex = cloneResult.left().value();
933 TitanOperationStatus status = titanDao.createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
934 if (status != TitanOperationStatus.OK) {
935 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
936 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
937 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
940 if (result == null) {
941 Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
942 GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
943 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
944 if (updateCatalogRes != StorageOperationStatus.OK) {
945 return Either.right(updateCatalogRes);
947 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
948 if (result.isRight()) {
951 ToscaElement toscaElement = result.left().value();
952 if (toscaElement.getToscaType() == ToscaElementTypeEnum.TopologyTemplate) {
953 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
960 private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
961 ToscaElement toscaElement) {
962 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
963 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
964 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
965 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
966 Map<String, ToscaElement> origCompMap = new HashMap<>();
967 if (instInputs == null) {
968 instInputs = new HashMap<>();
970 if (instGroups == null) {
971 instGroups = new HashMap<>();
973 if (instArtifactsMap == null) {
974 instArtifactsMap = new HashMap<>();
976 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
977 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
978 boolean needUpdateComposition = false;
980 if (instancesMap != null && !instancesMap.isEmpty()) {
981 for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
982 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
983 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
984 collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
986 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
987 if (needUpdateComposition) {
988 instancesMap.put(vfInst.getUniqueId(), vfInst);
991 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add to graph instInputs {} instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
992 if (!instInputs.isEmpty()) {
993 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
994 GraphVertex toscaDataVertex = null;
995 Either<GraphVertex, TitanOperationStatus> instInpVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
996 if (instInpVertexEither.isLeft()) {
997 toscaDataVertex = instInpVertexEither.left().value();
1000 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
1001 if (status != StorageOperationStatus.OK) {
1002 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
1003 result = Either.right(status);
1008 if (!instGroups.isEmpty()) {
1009 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
1010 GraphVertex toscaDataVertex = null;
1011 Either<GraphVertex, TitanOperationStatus> instGrVertexEither = titanDao.getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
1012 if (instGrVertexEither.isLeft()) {
1013 toscaDataVertex = instGrVertexEither.left().value();
1016 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
1017 if (status != StorageOperationStatus.OK) {
1018 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
1019 result = Either.right(status);
1024 if (needUpdateComposition) {
1025 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before update Instances ");
1026 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
1027 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
1028 compositionDataDefinition.setComponentInstances(instancesMap);
1029 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(clonedVertex);
1030 if (updateElement.isRight()) {
1031 TitanOperationStatus status = updateElement.right().value();
1032 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
1033 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
1038 result = operation.getToscaElement(clonedVertex.getUniqueId());
1041 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
1046 // TODO remove after jsonModelMigration
1047 public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
1048 return fixToscaComponentName(vfInst, origCompMap);
1051 private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
1052 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
1053 String ciUid = vfInst.getUniqueId();
1054 String origCompUid = vfInst.getComponentUid();
1055 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
1056 ToscaElement origComp = null;
1057 if (!origCompMap.containsKey(origCompUid)) {
1058 Either<ToscaElement, StorageOperationStatus> origCompEither;
1059 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
1060 origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1062 origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
1064 if (origCompEither.isRight()) {
1065 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1068 origComp = origCompEither.left().value();
1069 origCompMap.put(origCompUid, origComp);
1071 origComp = origCompMap.get(origCompUid);
1073 String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
1074 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
1075 vfInst.setToscaComponentName(toscaName);
1081 private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
1082 boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
1083 String ciUid = vfInst.getUniqueId();
1084 String origCompUid = vfInst.getComponentUid();
1085 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
1086 TopologyTemplate origComp = null;
1087 if (!origCompMap.containsKey(origCompUid)) {
1088 Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
1089 if (origCompEither.isRight()) {
1090 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
1093 origComp = (TopologyTemplate) origCompEither.left().value();
1094 origCompMap.put(origCompUid, origComp);
1096 origComp = (TopologyTemplate) origCompMap.get(origCompUid);
1098 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
1100 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
1101 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
1102 if (origInputs != null) {
1103 if (!instInputs.containsKey(ciUid)) {
1104 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
1105 instInputs.put(ciUid, instProperties);
1108 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
1109 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
1110 origInputs.forEach((propName, propMap) -> {
1111 if (!instProp.containsKey(propName)) {
1112 instProp.put(propName, propMap);
1116 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
1119 if (isAddInstGroup) {
1120 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "before create group instance. ");
1121 List<GroupDataDefinition> filteredGroups = null;
1123 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1124 if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
1125 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
1126 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1128 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
1129 if (CollectionUtils.isNotEmpty(filteredGroups)) {
1130 MapArtifactDataDefinition instArifacts = null;
1131 if (!instArtifactsMap.containsKey(ciUid)) {
1133 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "istance artifacts not found ");
1135 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
1137 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
1138 addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
1140 instArtifactsMap.put(ciUid, instArifacts);
1143 instArifacts = instArtifactsMap.get(ciUid);
1146 if (instArifacts != null) {
1147 Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
1149 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
1150 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
1151 for (GroupDataDefinition group : filteredGroups) {
1152 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance {} ", group.getName());
1153 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
1154 List<String> artifactsUid = new ArrayList<>();
1155 List<String> artifactsId = new ArrayList<>();
1156 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
1157 // CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "create new groupInstance {} ", artifact.getA);
1158 Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
1159 if (op.isPresent()) {
1160 artifactsUid.add(artifact.getArtifactUUID());
1161 artifactsId.add(artifact.getUniqueId());
1165 groupInstance.setGroupInstanceArtifacts(artifactsId);
1166 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
1167 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
1169 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
1170 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
1178 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
1179 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1180 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
1181 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1182 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1183 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1184 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1185 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1187 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1188 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1189 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
1190 if (isFirstCheckoutAfterCertification(nextVersion)) {
1191 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
1193 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
1194 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
1195 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1197 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
1198 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
1200 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1201 nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
1202 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1204 long currTime = System.currentTimeMillis();
1205 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
1206 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
1207 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1208 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1209 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
1210 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
1213 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1214 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1216 return nextVersionToscaElementVertex;
1219 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1220 Either<GraphVertex, StorageOperationStatus> result;
1221 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
1222 GraphVertex clonedToscaElement = null;
1223 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
1224 if (result.isRight()) {
1225 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
1227 clonedToscaElement = result.left().value();
1228 StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
1229 if (updateEdgeToCatalog != StorageOperationStatus.OK) {
1230 return Either.right(updateEdgeToCatalog);
1232 deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
1233 if (deleteResult.isRight()) {
1234 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
1235 result = Either.right(deleteResult.right().value());
1238 if (result.isLeft()) {
1239 result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
1244 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
1245 Either<GraphVertex, StorageOperationStatus> result = null;
1246 Vertex previousCertifiedToscaElement = null;
1247 if (majorVersion > 0) {
1248 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
1250 if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
1251 result = Either.right(StorageOperationStatus.NOT_FOUND);
1253 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
1254 if (previousCertifiedToscaElement == null) {
1255 result = Either.right(StorageOperationStatus.NOT_FOUND);
1258 if (result == null) {
1259 TitanOperationStatus status = titanDao.createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
1260 if (status != TitanOperationStatus.OK) {
1261 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
1262 previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
1263 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
1268 if (result == null) {
1269 result = Either.left(clonedToscaElement);
1274 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
1276 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
1277 if (edges.hasNext()) {
1278 return edges.next().outVertex();
1283 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
1284 Either<List<GraphVertex>, StorageOperationStatus> result = null;
1286 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
1287 List<GraphVertex> previosVersions = null;
1288 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
1289 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
1291 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
1292 properties.put(GraphPropertyEnum.UUID, uuid);
1293 properties.put(GraphPropertyEnum.NAME, componentName);
1294 Either<List<GraphVertex>, TitanOperationStatus> getToscaElementsRes = titanDao.getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
1295 if (getToscaElementsRes.isRight()) {
1296 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getToscaElementsRes.right().value()));
1298 if (result == null) {
1299 previosVersions = getToscaElementsRes.left().value();
1300 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
1301 if (deleteResult.isRight()) {
1302 result = Either.right(deleteResult.right().value());
1305 if (result == null) {
1306 result = Either.left(previosVersions);
1308 } catch (Exception e) {
1309 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
1314 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
1316 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
1317 String uniqueId = IdBuilderUtils.generateUniqueId();
1318 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
1319 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
1320 nextVersionToscaElementVertex.setUniqueId(uniqueId);
1321 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
1322 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
1324 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
1325 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
1326 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMETER + "0");
1327 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1328 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1329 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
1330 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
1331 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
1332 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
1334 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE && toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED)) {
1335 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.getValue());
1337 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
1338 nextVersionToscaElementVertex.setMetadataJson(new HashMap<String, Object>(toscaElementVertex.getMetadataJson()));
1339 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
1341 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
1342 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
1344 return nextVersionToscaElementVertex;
1347 private ComponentParametersView buildComponentParametersViewAfterCheckin() {
1348 ComponentParametersView componentParametersView = new ComponentParametersView();
1349 componentParametersView.disableAll();
1350 componentParametersView.setIgnoreUsers(false);
1351 return componentParametersView;
1354 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
1355 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
1356 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
1357 if (result.isLeft()) {
1358 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
1359 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
1360 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
1362 if (result.isLeft()) {
1363 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
1364 if (updateRelationsRes.isRight()) {
1365 result = Either.right(updateRelationsRes.right().value());
1371 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
1373 Either<GraphVertex, StorageOperationStatus> result;
1375 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(toscaElementVertex);
1376 if (updateVertexRes.isRight()) {
1377 TitanOperationStatus titatStatus = updateVertexRes.right().value();
1378 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
1379 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus));
1381 result = Either.left(updateVertexRes.left().value());
1386 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1387 Either<GraphVertex, StorageOperationStatus> result = null;
1388 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
1389 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
1391 if (currState == LifecycleStateEnum.READY_FOR_CERTIFICATION) {
1392 // In case of cancel "ready for certification" remove last state edge with "STATE" property equals to "NOT_CERTIFIED_CHECKIN"
1393 Map<GraphPropertyEnum, Object> vertexProperties = new HashMap<>();
1394 vertexProperties.put(GraphPropertyEnum.STATE, nextState);
1395 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteBelongingEdgeByCriteria(toscaElementVertex, EdgeLabelEnum.LAST_STATE, vertexProperties);
1396 if (deleteResult.isRight()) {
1397 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId(), deleteResult.right().value());
1398 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to update last state relation");
1399 result = Either.right(StorageOperationStatus.INCONSISTENCY);
1402 if (result == null) {
1403 // Remove CHECKOUT relation
1404 Either<Edge, TitanOperationStatus> deleteEdgeResult = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
1405 if (deleteEdgeResult.isRight()) {
1406 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1407 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeResult.right().value()));
1410 if (result == null) {
1411 // Create CHECKIN relation
1412 Map<EdgePropertyEnum, Object> edgeProperties = new HashMap<>();
1413 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
1414 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
1415 if (createEdgeRes != TitanOperationStatus.OK) {
1416 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
1417 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1420 if (result == null) {
1421 result = Either.left(toscaElementVertex);
1426 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
1427 Either<GraphVertex, StorageOperationStatus> result = null;
1428 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
1429 Either<Edge, TitanOperationStatus> deleteEdgeRes = titanDao.deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1430 if (deleteEdgeRes.isRight()) {
1431 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1432 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteEdgeRes.right().value()));
1434 if (result == null) {
1435 TitanOperationStatus createEdgeRes = titanDao.createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1437 if (createEdgeRes != TitanOperationStatus.OK) {
1438 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1439 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createEdgeRes));
1441 result = Either.left(modifierVertex);
1445 result = Either.left(ownerVertex);
1450 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1451 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1452 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1453 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1454 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1455 return verticesToGetParameters;
1458 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1459 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1460 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1461 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1462 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1463 return verticesToGetParameters;
1466 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1467 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1468 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1469 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1470 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1471 return verticesToGetParameters;
1474 private String getNextCertifiedVersion(String version) {
1475 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1476 Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
1477 return nextMajorVersion + VERSION_DELIMETER + "0";
1480 private String getNextVersion(String currVersion) {
1481 String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP);
1482 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1483 return versionParts[0] + VERSION_DELIMETER + minorVersion;
1486 private Integer getMinorVersion(String version) {
1487 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1488 return Integer.parseInt(versionParts[1]);
1491 private Integer getMajorVersion(String version) {
1492 String[] versionParts = version.split(VERSION_DELIMETER_REGEXP);
1493 return Integer.parseInt(versionParts[0]);
1496 private boolean isFirstCheckoutAfterCertification(String version) {
1497 if (Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMETER_REGEXP)[1]) == 1) {
1503 public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
1504 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
1505 Either<ToscaElement, StorageOperationStatus> result = null;
1506 GraphVertex toscaElement = null;
1507 GraphVertex modifier = null;
1510 Either<Map<String, GraphVertex>, TitanOperationStatus> getVerticesRes = titanDao.getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
1511 if (getVerticesRes.isRight()) {
1512 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
1513 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVerticesRes.right().value()));
1515 if (result == null) {
1516 toscaElement = getVerticesRes.left().value().get(toscaElementId);
1517 modifier = getVerticesRes.left().value().get(modifierId);
1518 owner = getVerticesRes.left().value().get(ownerId);
1520 StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
1521 if (status != StorageOperationStatus.OK) {
1522 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
1525 if (result == null) {
1526 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
1528 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1529 toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
1531 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
1532 if (resultUpdate.isRight()) {
1533 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
1534 result = Either.right(resultUpdate.right().value());
1537 if (result == null) {
1538 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
1539 result = operation.getToscaElement(toscaElement.getUniqueId());
1543 } catch (Exception e) {
1544 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
1549 private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
1551 StorageOperationStatus result = null;
1552 TitanOperationStatus status = titanDao.replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
1553 if (status != TitanOperationStatus.OK) {
1554 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1556 if (result == null) {
1557 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
1558 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
1559 status = titanDao.createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
1560 if (status != TitanOperationStatus.OK) {
1561 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
1562 result = DaoStatusConverter.convertTitanStatusToStorageStatus(status);
1565 if (result == null) {
1566 result = StorageOperationStatus.OK;
1571 private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
1572 Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
1573 if (catalog.isRight()) {
1574 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
1575 return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
1577 GraphVertex catalogV = catalog.left().value();
1578 if (newVersionV != null) {
1579 Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1580 if (isAbstract == null || !isAbstract) {
1581 // no new vertex, only delete previous
1582 TitanOperationStatus result = titanDao.createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
1583 if (result != TitanOperationStatus.OK) {
1584 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
1585 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
1589 if (prevVersionV != null) {
1590 Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1591 if (isAbstract == null || !isAbstract) {
1592 // if prev == null -> new resource was added
1593 Either<Edge, TitanOperationStatus> deleteResult = titanDao.deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
1594 if (deleteResult.isRight()) {
1595 CommonUtility.addRecordToLog(logger, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
1596 return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteResult.right().value());
1600 return StorageOperationStatus.OK;