2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
23 import org.janusgraph.core.JanusGraphVertex;
24 import fj.data.Either;
25 import org.apache.commons.collections.CollectionUtils;
26 import org.apache.commons.collections.MapUtils;
27 import org.apache.commons.lang.StringUtils;
28 import org.apache.commons.lang3.tuple.ImmutablePair;
29 import org.apache.tinkerpop.gremlin.structure.Direction;
30 import org.apache.tinkerpop.gremlin.structure.Edge;
31 import org.apache.tinkerpop.gremlin.structure.Vertex;
32 import org.openecomp.sdc.be.config.ConfigurationManager;
33 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
34 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
35 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
36 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
37 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
38 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
39 import org.openecomp.sdc.be.dao.jsongraph.utils.IdBuilderUtils;
40 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
41 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
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.DistributionStatusEnum;
49 import org.openecomp.sdc.be.model.LifecycleStateEnum;
50 import org.openecomp.sdc.be.model.User;
51 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.TopologyTemplate;
52 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElement;
53 import org.openecomp.sdc.be.model.jsonjanusgraph.datamodel.ToscaElementTypeEnum;
54 import org.openecomp.sdc.be.model.jsonjanusgraph.enums.JsonConstantKeysEnum;
55 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
56 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
57 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
58 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
59 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
60 import org.openecomp.sdc.common.log.wrappers.Logger;
63 import java.util.stream.Collectors;
65 @org.springframework.stereotype.Component("tosca-element-lifecycle-operation")
68 * Allows to perform lifecycle operations: checkin, checkout, submit for testing, start certification and certification process for tosca element
70 public class ToscaElementLifecycleOperation extends BaseOperation {
72 private static final String FAILED_TO_DELETE_LAST_STATE_EDGE_STATUS_IS = "Failed to delete last state edge. Status is {}. ";
73 private static final String FAILED_TO_GET_VERTICES = "Failed to get vertices by id {}. Status is {}. ";
74 public static final String VERSION_DELIMITER = ".";
75 public static final String VERSION_DELIMITER_REGEXP = "\\.";
77 private static final Logger log = Logger.getLogger(ToscaElementLifecycleOperation.class);
80 * Performs changing a lifecycle state of tosca element from "checked out" or "ready for certification" to "checked in"
83 * @param toscaElementId
88 public Either<ToscaElement, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, String toscaElementId, String modifierId, String ownerId) {
89 Either<GraphVertex, StorageOperationStatus> updateResult = null;
90 Either<ToscaElement, StorageOperationStatus> result = null;
91 Map<String, GraphVertex> vertices = null;
92 ToscaElementOperation operation;
94 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
95 .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.convertJanusGraphStatusToStorageStatus(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, JanusGraphOperationStatus> getToscaElementRes = janusGraphDao
128 .getVertexById(toscaElementId, JsonParseFlagEnum.NoParse);
129 if (getToscaElementRes.isRight()) {
130 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
132 if (result == null) {
133 toscaElement = getToscaElementRes.left().value();
134 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
135 if (vertices == null || !vertices.hasNext()) {
136 result = Either.right(StorageOperationStatus.NOT_FOUND);
138 result = Either.left(convertToUser(vertices.next()));
145 * Returns vertex presenting owner of tosca element specified by uniqueId
147 * @param toscaElement
150 public Either<User, StorageOperationStatus> getToscaElementOwner(GraphVertex toscaElement) {
151 Either<User, StorageOperationStatus> result = null;
152 Iterator<Vertex> vertices = toscaElement.getVertex().vertices(Direction.IN, EdgeLabelEnum.STATE.name());
153 if (vertices == null || !vertices.hasNext()) {
154 result = Either.right(StorageOperationStatus.NOT_FOUND);
156 result = Either.left(convertToUser(vertices.next()));
162 * Performs checkout of a tosca element
164 * @param toscaElementId
169 public Either<ToscaElement, StorageOperationStatus> checkoutToscaElement(String toscaElementId, String modifierId, String ownerId) {
170 Either<ToscaElement, StorageOperationStatus> result = null;
171 Map<String, GraphVertex> vertices = null;
173 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
174 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForCheckout(toscaElementId, modifierId, ownerId));
175 if (getVerticesRes.isRight()) {
176 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
177 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
179 if (result == null) {
180 vertices = getVerticesRes.left().value();
181 // update previous component if not certified
182 StorageOperationStatus status = updatePreviousVersion(vertices.get(toscaElementId), vertices.get(ownerId));
183 if (status != StorageOperationStatus.OK) {
184 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update vertex with id {} . Status is {}. ", status);
185 result = Either.right(status);
188 if (result == null) {
189 result = cloneToscaElementForCheckout(vertices.get(toscaElementId), vertices.get(modifierId));
190 if (result.isRight()) {
191 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to checkout tosca element {}. Status is {} ", toscaElementId, result.right().value());
195 } catch (Exception e) {
196 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during checkout tosca element {}. {}", toscaElementId, e.getMessage());
202 * Performs undo checkout for tosca element
204 * @param toscaElementId
207 public Either<ToscaElement, StorageOperationStatus> undoCheckout(String toscaElementId) {
208 Either<ToscaElement, StorageOperationStatus> result = null;
209 Either<GraphVertex, JanusGraphOperationStatus> getToscaElementRes = null;
210 Iterator<Edge> nextVersionComponentIter = null;
211 ToscaElementOperation operation;
212 Vertex preVersionVertex = null;
214 getToscaElementRes = janusGraphDao.getVertexById(toscaElementId, JsonParseFlagEnum.ParseMetadata);
215 if (getToscaElementRes.isRight()) {
216 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
217 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementRes.right().value()));
219 GraphVertex currVersionV = getToscaElementRes.left().value();
220 if (result == null && hasPreviousVersion(currVersionV)) {
221 // find previous version
222 nextVersionComponentIter = currVersionV.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
223 if (nextVersionComponentIter == null || !nextVersionComponentIter.hasNext()) {
224 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch previous version of tosca element with name {}. ", currVersionV.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString());
225 result = Either.right(StorageOperationStatus.NOT_FOUND);
227 if (result == null) {
228 preVersionVertex = nextVersionComponentIter.next().outVertex();
229 StorageOperationStatus updateOldResourceResult = updateOldToscaElementBeforeUndoCheckout(preVersionVertex);
230 if (updateOldResourceResult != StorageOperationStatus.OK) {
231 result = Either.right(updateOldResourceResult);
235 if (result == null) {
236 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRootByUndoCheckout((JanusGraphVertex) preVersionVertex, currVersionV);
237 if (updateCatalogRes != StorageOperationStatus.OK) {
238 return Either.right(updateCatalogRes);
240 operation = getToscaElementOperation(currVersionV.getLabel());
241 result = operation.deleteToscaElement(currVersionV);
242 if (result.isRight()) {
245 if(preVersionVertex != null){
246 String uniqueIdPreVer = (String) janusGraphDao.getProperty((JanusGraphVertex) preVersionVertex, GraphPropertyEnum.UNIQUE_ID.getProperty());
247 result = operation.getToscaElement(uniqueIdPreVer);
249 result = Either.left(null);
252 } catch (Exception e) {
253 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during undo checkout tosca element {}. {}", toscaElementId, e.getMessage());
258 private boolean hasPreviousVersion(GraphVertex toscaElementVertex) {
259 boolean hasPreviousVersion = true;
260 String version = (String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION);
261 if (StringUtils.isEmpty(version) || "0.1".equals(version))
262 hasPreviousVersion = false;
263 return hasPreviousVersion;
266 public Either<ToscaElement, StorageOperationStatus> certifyToscaElement(String toscaElementId, String modifierId, String ownerId) {
267 Either<ToscaElement, StorageOperationStatus> result = null;
268 Either<GraphVertex, StorageOperationStatus> cloneRes = null;
269 GraphVertex toscaElement = null;
270 GraphVertex modifier = null;
271 GraphVertex certifiedToscaElement = null;
272 Integer majorVersion = null;
274 StorageOperationStatus status;
276 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
277 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
278 if (getVerticesRes.isRight()) {
279 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
280 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
282 if (result == null) {
283 toscaElement = getVerticesRes.left().value().get(toscaElementId);
284 modifier = getVerticesRes.left().value().get(modifierId);
285 majorVersion = getMajorVersion((String) toscaElement.getMetadataProperty(GraphPropertyEnum.VERSION));
286 status = handleRelationsOfPreviousToscaElementBeforeCertifying(toscaElement, modifier, majorVersion);
287 if (status != StorageOperationStatus.OK) {
288 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of previous tosca element before certifying {}. Status is {}. ", toscaElement.getUniqueId(), status);
291 if (result == null) {
292 cloneRes = cloneToscaElementForCertify(toscaElement, modifier, majorVersion);
293 if (cloneRes.isRight()) {
294 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element during certification. ");
295 result = Either.right(cloneRes.right().value());
297 certifiedToscaElement = cloneRes.left().value();
298 status = handleRelationsOfNewestCertifiedToscaElement(toscaElement, certifiedToscaElement);
299 if (status != StorageOperationStatus.OK) {
300 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations of newest certified tosca element {}. Status is {}. ", certifiedToscaElement.getUniqueId(), status);
304 if (result == null) {
305 return getToscaElementOperation(toscaElement.getLabel()).getToscaElement(certifiedToscaElement.getUniqueId());
307 } catch (Exception e) {
308 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during certification tosca element {}. {}", toscaElementId, e.getMessage());
313 private StorageOperationStatus handleRelationsOfNewestCertifiedToscaElement(GraphVertex toscaElement, GraphVertex certifiedToscaElement) {
315 JanusGraphOperationStatus createVersionEdgeStatus = janusGraphDao.createEdge(toscaElement, certifiedToscaElement, EdgeLabelEnum.VERSION, new HashMap<>());
316 if (createVersionEdgeStatus != JanusGraphOperationStatus.OK) {
317 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create version edge from last element {} to new certified element {}. status=", toscaElement.getUniqueId(), certifiedToscaElement.getUniqueId(),
318 createVersionEdgeStatus);
319 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createVersionEdgeStatus);
321 return StorageOperationStatus.OK;
324 public Either<GraphVertex, JanusGraphOperationStatus> findUser(String userId) {
325 return findUserVertex(userId);
328 private Either<Boolean, StorageOperationStatus> markToscaElementsAsDeleted(ToscaElementOperation operation, List<GraphVertex> toscaElements) {
329 Either<Boolean, StorageOperationStatus> result = Either.left(true);
330 for (GraphVertex resourceToDelete : toscaElements) {
331 if (!(resourceToDelete.getJsonMetadataField(JsonPresentationFields.LIFECYCLE_STATE)).equals(LifecycleStateEnum.CERTIFIED.name())) {
332 Either<GraphVertex, StorageOperationStatus> deleteElementRes = operation.markComponentToDelete(resourceToDelete);
333 if (deleteElementRes.isRight()) {
334 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete tosca element {}. Status is {}. ", resourceToDelete.getUniqueId(), deleteElementRes.right().value());
335 result = Either.right(deleteElementRes.right().value());
343 private StorageOperationStatus handleRelationsOfPreviousToscaElementBeforeCertifying(GraphVertex toscaElement, GraphVertex modifier, Integer majorVersion) {
344 StorageOperationStatus result = null;
345 if (majorVersion > 0) {
346 Either<Vertex, StorageOperationStatus> findRes = findLastCertifiedToscaElementVertex(toscaElement);
347 if (findRes.isRight()) {
348 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last certified tosca element {} . Status is {}. ", toscaElement.getMetadataProperty(GraphPropertyEnum.NAME), findRes.right().value());
349 result = findRes.right().value();
351 if (result == null) {
352 Vertex lastCertifiedVertex = findRes.left().value();
353 Map<GraphPropertyEnum, Object> properties = new EnumMap<>(GraphPropertyEnum.class);
354 properties.put(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
355 JanusGraphOperationStatus status = janusGraphDao
356 .updateVertexMetadataPropertiesWithJson(lastCertifiedVertex, properties);
357 if (status != JanusGraphOperationStatus.OK) {
358 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of tosca element {} to [{}]. Status is {}", toscaElement.getUniqueId(), false, status);
359 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
361 // remove previous certified version from the catalog
362 GraphVertex lastCertifiedV = new GraphVertex();
363 lastCertifiedV.setVertex((JanusGraphVertex) lastCertifiedVertex);
364 lastCertifiedV.setUniqueId((String) janusGraphDao
365 .getProperty((JanusGraphVertex) lastCertifiedVertex, GraphPropertyEnum.UNIQUE_ID.getProperty()));
366 StorageOperationStatus res = updateEdgeToCatalogRoot(null, lastCertifiedV);
367 if (res != StorageOperationStatus.OK) {
372 if (result == null) {
373 result = StorageOperationStatus.OK;
378 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertex(GraphVertex toscaElement) {
379 return findLastCertifiedToscaElementVertexRecursively(toscaElement.getVertex());
382 private Either<Vertex, StorageOperationStatus> findLastCertifiedToscaElementVertexRecursively(Vertex vertex) {
383 if (isCertifiedVersion((String) vertex.property(GraphPropertyEnum.VERSION.getProperty()).value())) {
384 return Either.left(vertex);
386 Iterator<Edge> edgeIter = vertex.edges(Direction.IN, EdgeLabelEnum.VERSION.name());
387 if (!edgeIter.hasNext()) {
388 return Either.right(StorageOperationStatus.NOT_FOUND);
390 return findLastCertifiedToscaElementVertexRecursively(edgeIter.next().outVertex());
393 private boolean isCertifiedVersion(String version) {
394 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
395 if (Integer.parseInt(versionParts[0]) > 0 && Integer.parseInt(versionParts[1]) == 0) {
401 private StorageOperationStatus updateOldToscaElementBeforeUndoCheckout(Vertex previousVersionToscaElement) {
403 StorageOperationStatus result = StorageOperationStatus.OK;
404 String previousVersion = (String) previousVersionToscaElement.property(GraphPropertyEnum.VERSION.getProperty()).value();
405 if (!previousVersion.endsWith(".0")) {
407 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to update vertex of previous version of tosca element", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
409 Map<String, Object> propertiesToUpdate = new HashMap<>();
410 propertiesToUpdate.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
411 Map<String, Object> jsonMetadataMap = JsonParserUtils.toMap((String) previousVersionToscaElement.property(GraphPropertyEnum.METADATA.getProperty()).value());
412 jsonMetadataMap.put(GraphPropertyEnum.IS_HIGHEST_VERSION.getProperty(), true);
413 propertiesToUpdate.put(GraphPropertyEnum.METADATA.getProperty(), JsonParserUtils.toJson(jsonMetadataMap));
415 janusGraphDao.setVertexProperties(previousVersionToscaElement, propertiesToUpdate);
417 Iterator<Edge> edgesIter = previousVersionToscaElement.edges(Direction.IN, EdgeLabelEnum.LAST_STATE.name());
418 if (!edgesIter.hasNext()) {
419 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch last modifier vertex for tosca element {}. ", previousVersionToscaElement.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()));
420 result = StorageOperationStatus.NOT_FOUND;
422 Edge lastStateEdge = edgesIter.next();
423 Vertex lastModifier = lastStateEdge.outVertex();
424 JanusGraphOperationStatus replaceRes = janusGraphDao
425 .replaceEdgeLabel(lastModifier, previousVersionToscaElement, lastStateEdge, EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE);
426 if (replaceRes != JanusGraphOperationStatus.OK) {
427 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to replace label from {} to {}. status = {}", EdgeLabelEnum.LAST_STATE, EdgeLabelEnum.STATE, replaceRes);
428 result = StorageOperationStatus.INCONSISTENCY;
429 if (replaceRes != JanusGraphOperationStatus.INVALID_ID) {
430 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(replaceRes);
435 } catch (Exception e) {
436 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during update previous tosca element {} before undo checkout. {} ", e.getMessage());
442 private StorageOperationStatus updatePreviousVersion(GraphVertex toscaElementVertex, GraphVertex ownerVertex) {
443 StorageOperationStatus result = null;
444 String ownerId = (String) ownerVertex.getMetadataProperty(GraphPropertyEnum.USERID);
445 String toscaElementId = toscaElementVertex.getUniqueId();
446 if (!toscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE).equals(LifecycleStateEnum.CERTIFIED.name())) {
447 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
448 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
449 if (updateVertexRes.isRight()) {
450 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
451 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update tosca element vertex {}. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
452 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus);
454 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = null;
455 if (result == null) {
456 CommonUtility.addRecordToLog(log, LogLevelEnum.TRACE, "Going to replace edge with label {} to label {} from {} to {}. ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId);
458 deleteEdgeRes = janusGraphDao
459 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
460 if (deleteEdgeRes.isRight()) {
461 JanusGraphOperationStatus janusGraphStatus = deleteEdgeRes.right().value();
462 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge with label {} from {} to {}. Status is {} ", EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE, ownerId, toscaElementId, janusGraphStatus);
463 if (!janusGraphStatus.equals(JanusGraphOperationStatus.INVALID_ID)) {
464 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(janusGraphStatus);
466 result = StorageOperationStatus.INCONSISTENCY;
470 if (result == null) {
471 JanusGraphOperationStatus
472 createEdgeRes = janusGraphDao
473 .createEdge(ownerVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_STATE, deleteEdgeRes.left().value());
474 if (createEdgeRes != JanusGraphOperationStatus.OK) {
475 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes);
479 if (result == null) {
480 result = StorageOperationStatus.OK;
485 private Either<ToscaElement, StorageOperationStatus> cloneToscaElementForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
487 Either<ToscaElement, StorageOperationStatus> result = null;
488 Either<GraphVertex, StorageOperationStatus> cloneResult = null;
489 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
490 // check if component with the next version doesn't exist.
491 Iterator<Edge> nextVersionComponentIter = toscaElementVertex.getVertex().edges(Direction.OUT, EdgeLabelEnum.VERSION.name());
492 if (nextVersionComponentIter != null && nextVersionComponentIter.hasNext()) {
493 Vertex nextVersionVertex = nextVersionComponentIter.next().inVertex();
494 String fetchedVersion = (String) nextVersionVertex.property(GraphPropertyEnum.VERSION.getProperty()).value();
495 String fetchedName = (String) nextVersionVertex.property(GraphPropertyEnum.NORMALIZED_NAME.getProperty()).value();
496 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. ",
497 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME).toString(), toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION).toString(), fetchedName, fetchedVersion);
498 result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS);
500 if (result == null) {
501 toscaElementVertex.getOrSetDefaultInstantiationTypeForToscaElementJson();
502 cloneResult = operation.cloneToscaElement(toscaElementVertex, cloneGraphVertexForCheckout(toscaElementVertex, modifierVertex), modifierVertex);
503 if (cloneResult.isRight()) {
504 result = Either.right(cloneResult.right().value());
507 GraphVertex clonedVertex = null;
508 if (result == null) {
509 clonedVertex = cloneResult.left().value();
510 JanusGraphOperationStatus
511 status = janusGraphDao
512 .createEdge(toscaElementVertex.getVertex(), cloneResult.left().value().getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
513 if (status != JanusGraphOperationStatus.OK) {
514 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
515 toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), cloneResult.left().value().getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
516 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
519 if (result == null) {
520 Boolean isHighest = (Boolean) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
521 GraphVertex prevVersionInCatalog = (isHighest != null && isHighest) ? null : toscaElementVertex;
522 StorageOperationStatus updateCatalogRes = updateEdgeToCatalogRoot(clonedVertex, prevVersionInCatalog);
523 if (updateCatalogRes != StorageOperationStatus.OK) {
524 return Either.right(updateCatalogRes);
526 result = operation.getToscaElement(cloneResult.left().value().getUniqueId());
527 if (result.isRight()) {
530 ToscaElement toscaElement = result.left().value();
531 if (toscaElement.getToscaType() == ToscaElementTypeEnum.TOPOLOGY_TEMPLATE) {
532 result = handleFixTopologyTemplate(toscaElementVertex, result, operation, clonedVertex, toscaElement);
539 private Either<ToscaElement, StorageOperationStatus> handleFixTopologyTemplate(GraphVertex toscaElementVertex, Either<ToscaElement, StorageOperationStatus> result, ToscaElementOperation operation, GraphVertex clonedVertex,
540 ToscaElement toscaElement) {
541 TopologyTemplate topologyTemplate = (TopologyTemplate) toscaElement;
542 Map<String, MapPropertiesDataDefinition> instInputs = topologyTemplate.getInstInputs();
543 Map<String, MapGroupsDataDefinition> instGroups = topologyTemplate.getInstGroups();
544 Map<String, MapArtifactDataDefinition> instArtifactsMap = topologyTemplate.getInstanceArtifacts();
545 Map<String, ToscaElement> origCompMap = new HashMap<>();
546 if (instInputs == null) {
547 instInputs = new HashMap<>();
549 if (instGroups == null) {
550 instGroups = new HashMap<>();
552 if (instArtifactsMap == null) {
553 instArtifactsMap = new HashMap<>();
555 Map<String, ComponentInstanceDataDefinition> instancesMap = topologyTemplate.getComponentInstances();
556 boolean isAddInstGroup = instGroups == null || instGroups.isEmpty();
557 boolean needUpdateComposition = false;
559 if (instancesMap != null && !instancesMap.isEmpty()) {
560 for (ComponentInstanceDataDefinition vfInst : instancesMap.values()) {
561 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "vfInst name is {} . OriginType {}. ", vfInst.getName(), vfInst.getOriginType());
562 if (vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
563 collectInstanceInputAndGroups(instInputs, instGroups, instArtifactsMap, origCompMap, isAddInstGroup, vfInst, clonedVertex);
565 needUpdateComposition = needUpdateComposition || fixToscaComponentName(vfInst, origCompMap);
566 if (needUpdateComposition) {
567 instancesMap.put(vfInst.getUniqueId(), vfInst);
570 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add to graph instInputs {} instGroups {} needUpdateComposition {}", instInputs, instGroups, needUpdateComposition);
571 if (!instInputs.isEmpty()) {
572 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst inputs {} ", instInputs == null ? 0 : instInputs.size());
573 GraphVertex toscaDataVertex = null;
574 Either<GraphVertex, JanusGraphOperationStatus> instInpVertexEither = janusGraphDao
575 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_INPUTS, JsonParseFlagEnum.ParseJson);
576 if (instInpVertexEither.isLeft()) {
577 toscaDataVertex = instInpVertexEither.left().value();
580 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_INPUTS, EdgeLabelEnum.INST_INPUTS, toscaDataVertex, instInputs);
581 if (status != StorageOperationStatus.OK) {
582 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance inputs . Status is {}. ", status);
583 result = Either.right(status);
588 if (!instGroups.isEmpty()) {
589 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before add inst groups {} ", instGroups == null ? 0 : instGroups.size());
590 GraphVertex toscaDataVertex = null;
591 Either<GraphVertex, JanusGraphOperationStatus> instGrVertexEither = janusGraphDao
592 .getChildVertex(toscaElementVertex, EdgeLabelEnum.INST_GROUPS, JsonParseFlagEnum.ParseJson);
593 if (instGrVertexEither.isLeft()) {
594 toscaDataVertex = instGrVertexEither.left().value();
597 StorageOperationStatus status = handleToscaData(clonedVertex, VertexTypeEnum.INST_GROUPS, EdgeLabelEnum.INST_GROUPS, toscaDataVertex, instGroups);
598 if (status != StorageOperationStatus.OK) {
599 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instance group . Status is {}. ", status);
600 result = Either.right(status);
605 if (needUpdateComposition) {
606 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before update Instances ");
607 Map<String, CompositionDataDefinition> jsonComposition = (Map<String, CompositionDataDefinition>) clonedVertex.getJson();
608 CompositionDataDefinition compositionDataDefinition = jsonComposition.get(JsonConstantKeysEnum.COMPOSITION.getValue());
609 compositionDataDefinition.setComponentInstances(instancesMap);
610 Either<GraphVertex, JanusGraphOperationStatus> updateElement = janusGraphDao.updateVertex(clonedVertex);
611 if (updateElement.isRight()) {
612 JanusGraphOperationStatus status = updateElement.right().value();
613 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update instances on metadata vertex . Status is {}. ", status);
614 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
619 result = operation.getToscaElement(clonedVertex.getUniqueId());
622 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "RI map empty on component {}", toscaElement.getUniqueId());
627 // TODO remove after jsonModelMigration
628 public boolean resolveToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
629 return fixToscaComponentName(vfInst, origCompMap);
632 private boolean fixToscaComponentName(ComponentInstanceDataDefinition vfInst, Map<String, ToscaElement> origCompMap) {
633 if (vfInst.getToscaComponentName() == null || vfInst.getToscaComponentName().isEmpty()) {
634 String ciUid = vfInst.getUniqueId();
635 String origCompUid = vfInst.getComponentUid();
636 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "fixToscaComponentName:: Ri id {} . origin component id is {}. type is{} ", ciUid, origCompUid, vfInst.getOriginType());
637 ToscaElement origComp = null;
638 if (!origCompMap.containsKey(origCompUid)) {
639 Either<ToscaElement, StorageOperationStatus> origCompEither;
640 if (vfInst.getOriginType() == null || vfInst.getOriginType().name().equals(OriginTypeEnum.VF.name())) {
641 origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
643 origCompEither = nodeTypeOperation.getToscaElement(origCompUid);
645 if (origCompEither.isRight()) {
646 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
649 origComp = origCompEither.left().value();
650 origCompMap.put(origCompUid, origComp);
652 origComp = origCompMap.get(origCompUid);
654 String toscaName = (String) origComp.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME);
655 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Origin component id is {}. toscaName {}", origCompUid, toscaName);
656 vfInst.setToscaComponentName(toscaName);
662 private void collectInstanceInputAndGroups(Map<String, MapPropertiesDataDefinition> instInputs, Map<String, MapGroupsDataDefinition> instGroups, Map<String, MapArtifactDataDefinition> instArtifactsMap, Map<String, ToscaElement> origCompMap,
663 boolean isAddInstGroup, ComponentInstanceDataDefinition vfInst, GraphVertex clonedVertex) {
664 String ciUid = vfInst.getUniqueId();
665 String origCompUid = vfInst.getComponentUid();
666 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "collectInstanceInputAndGroups:: Ri id {} . origin component id is {}. ", ciUid, origCompUid);
667 TopologyTemplate origComp = null;
668 if (!origCompMap.containsKey(origCompUid)) {
669 Either<ToscaElement, StorageOperationStatus> origCompEither = topologyTemplateOperation.getToscaElement(origCompUid);
670 if (origCompEither.isRight()) {
671 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to find orig component {} . Status is {}. ", origCompEither.right().value());
674 origComp = (TopologyTemplate) origCompEither.left().value();
675 origCompMap.put(origCompUid, origComp);
677 origComp = (TopologyTemplate) origCompMap.get(origCompUid);
679 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component {}. ", origComp.getUniqueId());
681 Map<String, PropertyDataDefinition> origInputs = origComp.getInputs();
682 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Orig component inputs size {}. ", origInputs == null ? 0 : origInputs.size());
683 if (origInputs != null) {
684 if (!instInputs.containsKey(ciUid)) {
685 MapPropertiesDataDefinition instProperties = new MapPropertiesDataDefinition(origInputs);
686 instInputs.put(ciUid, instProperties);
689 MapPropertiesDataDefinition instInputMap = instInputs.get(ciUid);
690 Map<String, PropertyDataDefinition> instProp = instInputMap.getMapToscaDataDefinition();
691 origInputs.forEach((propName, propMap) -> {
692 if (!instProp.containsKey(propName)) {
693 instProp.put(propName, propMap);
697 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "ComponentInstanseInputs {}. ", instInputs.get(ciUid));
700 if (isAddInstGroup) {
701 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "before create group instance. ");
702 List<GroupDataDefinition> filteredGroups = null;
704 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups before filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
705 if (origComp.getGroups() != null && !origComp.getGroups().isEmpty()) {
706 filteredGroups = origComp.getGroups().values().stream().filter(g -> g.getType().equals(VF_MODULE)).collect(Collectors.toList());
707 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups . Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
709 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check vf groups after filter. Size is {} ", filteredGroups == null ? 0 : filteredGroups.size());
710 if (CollectionUtils.isNotEmpty(filteredGroups)) {
711 MapArtifactDataDefinition instArifacts = null;
712 if (!instArtifactsMap.containsKey(ciUid)) {
714 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "istance artifacts not found ");
716 Map<String, ArtifactDataDefinition> deploymentArtifacts = origComp.getDeploymentArtifacts();
718 instArifacts = new MapArtifactDataDefinition(deploymentArtifacts);
719 addToscaDataDeepElementsBlockToToscaElement(clonedVertex, EdgeLabelEnum.INST_DEPLOYMENT_ARTIFACTS, VertexTypeEnum.INST_DEPLOYMENT_ARTIFACTS, instArifacts, ciUid);
721 instArtifactsMap.put(ciUid, instArifacts);
724 instArifacts = instArtifactsMap.get(ciUid);
727 if (instArifacts != null) {
728 Map<String, ArtifactDataDefinition> instDeplArtifMap = instArifacts.getMapToscaDataDefinition();
730 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "check group dep artifacts. Size is {} ", instDeplArtifMap == null ? 0 : instDeplArtifMap.values().size());
731 Map<String, GroupInstanceDataDefinition> groupInstanceToCreate = new HashMap<>();
732 for (GroupDataDefinition group : filteredGroups) {
733 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "create new groupInstance {} ", group.getName());
734 GroupInstanceDataDefinition groupInstance = buildGroupInstanceDataDefinition(group, vfInst, instDeplArtifMap);
735 List<String> artifactsUid = new ArrayList<>();
736 List<String> artifactsId = new ArrayList<>();
737 if (instDeplArtifMap!=null) {
738 for (ArtifactDataDefinition artifact : instDeplArtifMap.values()) {
739 Optional<String> op = group.getArtifacts().stream().filter(p -> p.equals(artifact.getGeneratedFromId())).findAny();
740 if (op.isPresent()) {
741 artifactsUid.add(artifact.getArtifactUUID());
742 artifactsId.add(artifact.getUniqueId());
747 groupInstance.setGroupInstanceArtifacts(artifactsId);
748 groupInstance.setGroupInstanceArtifactsUuid(artifactsUid);
749 groupInstanceToCreate.put(groupInstance.getName(), groupInstance);
751 if (MapUtils.isNotEmpty(groupInstanceToCreate)) {
752 instGroups.put(vfInst.getUniqueId(), new MapGroupsDataDefinition(groupInstanceToCreate));
760 private GraphVertex cloneGraphVertexForCheckout(GraphVertex toscaElementVertex, GraphVertex modifierVertex) {
761 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
762 String uniqueId = UniqueIdBuilder.buildComponentUniqueId();
763 Map<GraphPropertyEnum, Object> metadataProperties = new HashMap<>(toscaElementVertex.getMetadataProperties());
764 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
765 nextVersionToscaElementVertex.setUniqueId(uniqueId);
766 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
767 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
769 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
770 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
771 String nextVersion = getNextVersion((String) toscaElementVertex.getMetadataProperty(GraphPropertyEnum.VERSION));
772 if (isFirstCheckoutAfterCertification(nextVersion)) {
773 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UUID, IdBuilderUtils.generateUUID());
775 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, nextVersion);
776 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name());
777 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
779 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
780 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
782 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
783 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
784 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
786 long currTime = System.currentTimeMillis();
787 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, currTime);
788 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currTime);
789 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
790 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
791 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
792 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CONFORMANCE_LEVEL, ConfigurationManager.getConfigurationManager().getConfiguration().getToscaConformanceLevel());
795 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
796 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
798 return nextVersionToscaElementVertex;
801 private Either<GraphVertex, StorageOperationStatus> cloneToscaElementForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
802 Either<GraphVertex, StorageOperationStatus> result;
803 Either<List<GraphVertex>, StorageOperationStatus> deleteResult = null;
804 GraphVertex clonedToscaElement = null;
805 result = getToscaElementOperation(toscaElementVertex.getLabel()).cloneToscaElement(toscaElementVertex, cloneGraphVertexForCertify(toscaElementVertex, modifierVertex, majorVersion), modifierVertex);
806 if (result.isRight()) {
807 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} for certification. Sattus is {}. ", toscaElementVertex.getUniqueId(), result.right().value());
809 clonedToscaElement = result.left().value();
810 StorageOperationStatus updateEdgeToCatalog = updateEdgeToCatalogRoot(clonedToscaElement, toscaElementVertex);
811 if (updateEdgeToCatalog != StorageOperationStatus.OK) {
812 return Either.right(updateEdgeToCatalog);
814 deleteResult = deleteAllPreviousNotCertifiedVersions(toscaElementVertex);
815 if (deleteResult.isRight()) {
816 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete all previous npt certified versions of tosca element {}. Status is {}. ", toscaElementVertex.getUniqueId(), deleteResult.right().value());
817 result = Either.right(deleteResult.right().value());
820 if (result.isLeft()) {
821 result = handlePreviousVersionRelation(clonedToscaElement, deleteResult.left().value(), majorVersion);
826 private Either<GraphVertex, StorageOperationStatus> handlePreviousVersionRelation(GraphVertex clonedToscaElement, List<GraphVertex> deletedVersions, Integer majorVersion) {
827 Either<GraphVertex, StorageOperationStatus> result = null;
828 Vertex previousCertifiedToscaElement = null;
829 if (majorVersion > 0) {
830 List<GraphVertex> firstMinorVersionVertex = deletedVersions.stream().filter(gv -> getMinorVersion((String) gv.getMetadataProperty(GraphPropertyEnum.VERSION)) == 1).collect(Collectors.toList());
832 if (CollectionUtils.isEmpty(firstMinorVersionVertex)) {
833 result = Either.right(StorageOperationStatus.NOT_FOUND);
835 previousCertifiedToscaElement = getPreviousCertifiedToscaElement(firstMinorVersionVertex.get(0));
836 if (previousCertifiedToscaElement == null) {
837 result = Either.right(StorageOperationStatus.NOT_FOUND);
840 if (result == null) {
841 JanusGraphOperationStatus
842 status = janusGraphDao
843 .createEdge(previousCertifiedToscaElement, clonedToscaElement.getVertex(), EdgeLabelEnum.VERSION, new HashMap<>());
844 if (status != JanusGraphOperationStatus.OK) {
845 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.VERSION,
846 previousCertifiedToscaElement.property(GraphPropertyEnum.UNIQUE_ID.getProperty()), clonedToscaElement.getUniqueId(), status);
847 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status));
852 if (result == null) {
853 result = Either.left(clonedToscaElement);
858 private Vertex getPreviousCertifiedToscaElement(GraphVertex graphVertex) {
860 Iterator<Edge> edges = graphVertex.getVertex().edges(Direction.IN, EdgeLabelEnum.VERSION.name());
861 if (edges.hasNext()) {
862 return edges.next().outVertex();
867 private Either<List<GraphVertex>, StorageOperationStatus> deleteAllPreviousNotCertifiedVersions(GraphVertex toscaElementVertex) {
868 Either<List<GraphVertex>, StorageOperationStatus> result = null;
870 ToscaElementOperation operation = getToscaElementOperation(toscaElementVertex.getLabel());
871 List<GraphVertex> previosVersions = null;
872 Object uuid = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.UUID);
873 Object componentName = toscaElementVertex.getMetadataProperty(GraphPropertyEnum.NAME);
875 Map<GraphPropertyEnum, Object> properties = new HashMap<>();
876 properties.put(GraphPropertyEnum.UUID, uuid);
877 properties.put(GraphPropertyEnum.NAME, componentName);
878 Either<List<GraphVertex>, JanusGraphOperationStatus> getToscaElementsRes = janusGraphDao
879 .getByCriteria(toscaElementVertex.getLabel(), properties, JsonParseFlagEnum.ParseMetadata);
880 if (getToscaElementsRes.isRight()) {
881 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getToscaElementsRes.right().value()));
883 if (result == null) {
884 previosVersions = getToscaElementsRes.left().value();
885 Either<Boolean, StorageOperationStatus> deleteResult = markToscaElementsAsDeleted(operation, getToscaElementsRes.left().value());
886 if (deleteResult.isRight()) {
887 result = Either.right(deleteResult.right().value());
890 if (result == null) {
891 result = Either.left(previosVersions);
893 } catch (Exception e) {
894 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during deleteng all tosca elements by UUID {} and name {}. {} ", uuid, componentName, e.getMessage());
899 private GraphVertex cloneGraphVertexForCertify(GraphVertex toscaElementVertex, GraphVertex modifierVertex, Integer majorVersion) {
901 GraphVertex nextVersionToscaElementVertex = new GraphVertex();
902 String uniqueId = IdBuilderUtils.generateUniqueId();
903 Map<GraphPropertyEnum, Object> metadataProperties = new EnumMap<>(toscaElementVertex.getMetadataProperties());
904 nextVersionToscaElementVertex.setMetadataProperties(metadataProperties);
905 nextVersionToscaElementVertex.setUniqueId(uniqueId);
906 nextVersionToscaElementVertex.setLabel(toscaElementVertex.getLabel());
907 nextVersionToscaElementVertex.setType(toscaElementVertex.getType());
909 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, uniqueId);
910 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.COMPONENT_TYPE, nextVersionToscaElementVertex.getType().name());
911 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.VERSION, (majorVersion + 1) + VERSION_DELIMITER + "0");
912 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
913 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
914 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.CREATION_DATE, System.currentTimeMillis());
915 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, null);
916 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_CREATOR, modifierVertex.getUniqueId());
917 nextVersionToscaElementVertex.setJsonMetadataField(JsonPresentationFields.USER_ID_LAST_UPDATER, modifierVertex.getUniqueId());
919 if (toscaElementVertex.getType() == ComponentTypeEnum.SERVICE) {
920 nextVersionToscaElementVertex.addMetadataProperty(GraphPropertyEnum.DISTRIBUTION_STATUS, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name());
922 if (!MapUtils.isEmpty(toscaElementVertex.getMetadataJson())) {
923 nextVersionToscaElementVertex.setMetadataJson(new HashMap<>(toscaElementVertex.getMetadataJson()));
924 nextVersionToscaElementVertex.updateMetadataJsonWithCurrentMetadataProperties();
926 if (!MapUtils.isEmpty(toscaElementVertex.getJson())) {
927 nextVersionToscaElementVertex.setJson(new HashMap<String, ToscaDataDefinition>(toscaElementVertex.getJson()));
929 return nextVersionToscaElementVertex;
933 private Either<GraphVertex, StorageOperationStatus> checkinToscaELement(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex, LifecycleStateEnum nextState) {
934 Either<GraphVertex, StorageOperationStatus> updateRelationsRes;
935 Either<GraphVertex, StorageOperationStatus> result = changeStateToCheckedIn(currState, toscaElementVertex, ownerVertex, modifierVertex);
936 if (result.isLeft()) {
937 toscaElementVertex.addMetadataProperty(GraphPropertyEnum.STATE, nextState.name());
938 toscaElementVertex.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
939 result = updateToscaElementVertexMetadataPropertiesAndJson(toscaElementVertex);
941 if (result.isLeft()) {
942 updateRelationsRes = updateLastModifierEdge(toscaElementVertex, ownerVertex, modifierVertex);
943 if (updateRelationsRes.isRight()) {
944 result = Either.right(updateRelationsRes.right().value());
950 private Either<GraphVertex, StorageOperationStatus> updateToscaElementVertexMetadataPropertiesAndJson(GraphVertex toscaElementVertex) {
952 Either<GraphVertex, StorageOperationStatus> result;
954 Either<GraphVertex, JanusGraphOperationStatus> updateVertexRes = janusGraphDao.updateVertex(toscaElementVertex);
955 if (updateVertexRes.isRight()) {
956 JanusGraphOperationStatus titatStatus = updateVertexRes.right().value();
957 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update state of tosca element vertex {} metadata. Status is {}", toscaElementVertex.getUniqueId(), titatStatus);
958 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(titatStatus));
960 result = Either.left(updateVertexRes.left().value());
965 private Either<GraphVertex, StorageOperationStatus> changeStateToCheckedIn(LifecycleStateEnum currState, GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
966 Either<GraphVertex, StorageOperationStatus> result = null;
967 LifecycleStateEnum nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN;
968 String faileToUpdateStateMsg = "Failed to update state of tosca element {}. Status is {}";
970 // Remove CHECKOUT relation
971 Either<Edge, JanusGraphOperationStatus> deleteEdgeResult = janusGraphDao
972 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.STATE);
973 if (deleteEdgeResult.isRight()) {
974 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
975 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeResult.right().value()));
978 if (result == null) {
979 // Create CHECKIN relation
980 Map<EdgePropertyEnum, Object> edgeProperties = new EnumMap<>(EdgePropertyEnum.class);
981 edgeProperties.put(EdgePropertyEnum.STATE, nextState);
982 JanusGraphOperationStatus
983 createEdgeRes = janusGraphDao
984 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.STATE, edgeProperties);
985 if (createEdgeRes != JanusGraphOperationStatus.OK) {
986 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, faileToUpdateStateMsg, toscaElementVertex.getUniqueId());
987 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
990 if (result == null) {
991 result = Either.left(toscaElementVertex);
996 private Either<GraphVertex, StorageOperationStatus> updateLastModifierEdge(GraphVertex toscaElementVertex, GraphVertex ownerVertex, GraphVertex modifierVertex) {
997 Either<GraphVertex, StorageOperationStatus> result = null;
998 if (!modifierVertex.getMetadataProperties().get(GraphPropertyEnum.USERID).equals(ownerVertex.getMetadataProperties().get(GraphPropertyEnum.USERID))) {
999 Either<Edge, JanusGraphOperationStatus> deleteEdgeRes = janusGraphDao
1000 .deleteEdge(ownerVertex, toscaElementVertex, EdgeLabelEnum.LAST_MODIFIER);
1001 if (deleteEdgeRes.isRight()) {
1002 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete last modifier {} to tosca element {}. Edge type is {}", ownerVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1003 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteEdgeRes.right().value()));
1005 if (result == null) {
1006 JanusGraphOperationStatus createEdgeRes = janusGraphDao
1007 .createEdge(modifierVertex.getVertex(), toscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
1009 if (createEdgeRes != JanusGraphOperationStatus.OK) {
1010 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to associate user {} to component {}. Edge type is {}", modifierVertex.getUniqueId(), ownerVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
1011 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(createEdgeRes));
1013 result = Either.left(modifierVertex);
1017 result = Either.left(ownerVertex);
1022 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckin(String toscaElementId, String modifierId, String ownerId) {
1023 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1024 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseMetadata));
1025 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1026 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1027 return verticesToGetParameters;
1030 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForRequestCertification(String toscaElementId, String modifierId, String ownerId) {
1031 Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> verticesToGetParameters = new HashMap<>();
1032 verticesToGetParameters.put(toscaElementId, new ImmutablePair<>(GraphPropertyEnum.UNIQUE_ID, JsonParseFlagEnum.ParseAll));
1033 verticesToGetParameters.put(modifierId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1034 verticesToGetParameters.put(ownerId, new ImmutablePair<>(GraphPropertyEnum.USERID, JsonParseFlagEnum.NoParse));
1035 return verticesToGetParameters;
1038 private Map<String, ImmutablePair<GraphPropertyEnum, JsonParseFlagEnum>> prepareParametersToGetVerticesForCheckout(String toscaElementId, String modifierId, String ownerId) {
1039 //Implementation is currently identical
1040 return prepareParametersToGetVerticesForRequestCertification(toscaElementId,modifierId, ownerId);
1043 private String getNextCertifiedVersion(String version) {
1044 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1045 Integer nextMajorVersion = Integer.parseInt(versionParts[0]) + 1;
1046 return nextMajorVersion + VERSION_DELIMITER + "0";
1049 private String getNextVersion(String currVersion) {
1050 String[] versionParts = currVersion.split(VERSION_DELIMITER_REGEXP);
1051 Integer minorVersion = Integer.parseInt(versionParts[1]) + 1;
1052 return versionParts[0] + VERSION_DELIMITER + minorVersion;
1055 private Integer getMinorVersion(String version) {
1056 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1057 return Integer.parseInt(versionParts[1]);
1060 private Integer getMajorVersion(String version) {
1061 String[] versionParts = version.split(VERSION_DELIMITER_REGEXP);
1062 return Integer.parseInt(versionParts[0]);
1065 private boolean isFirstCheckoutAfterCertification(String version) {
1066 return (Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[0]) != 0 && Integer.parseInt(version.split(VERSION_DELIMITER_REGEXP)[1]) == 1);
1069 public Either<ToscaElement, StorageOperationStatus> forceCerificationOfToscaElement(String toscaElementId, String modifierId, String ownerId, String currVersion) {
1070 Either<GraphVertex, StorageOperationStatus> resultUpdate = null;
1071 Either<ToscaElement, StorageOperationStatus> result = null;
1072 GraphVertex toscaElement = null;
1073 GraphVertex modifier = null;
1076 Either<Map<String, GraphVertex>, JanusGraphOperationStatus> getVerticesRes = janusGraphDao
1077 .getVerticesByUniqueIdAndParseFlag(prepareParametersToGetVerticesForRequestCertification(toscaElementId, modifierId, ownerId));
1078 if (getVerticesRes.isRight()) {
1079 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, FAILED_TO_GET_VERTICES, toscaElementId);
1080 result = Either.right(DaoStatusConverter.convertJanusGraphStatusToStorageStatus(getVerticesRes.right().value()));
1082 if (result == null) {
1083 toscaElement = getVerticesRes.left().value().get(toscaElementId);
1084 modifier = getVerticesRes.left().value().get(modifierId);
1085 owner = getVerticesRes.left().value().get(ownerId);
1087 StorageOperationStatus status = handleRelationsUponForceCertification(toscaElement, modifier, owner);
1088 if (status != StorageOperationStatus.OK) {
1089 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to handle relations on certification request for tosca element {}. Status is {}. ", toscaElement.getUniqueId(), status);
1092 if (result == null) {
1093 LifecycleStateEnum nextState = LifecycleStateEnum.CERTIFIED;
1095 toscaElement.addMetadataProperty(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1096 toscaElement.addMetadataProperty(GraphPropertyEnum.VERSION, getNextCertifiedVersion(currVersion));
1098 resultUpdate = updateToscaElementVertexMetadataPropertiesAndJson(toscaElement);
1099 if (resultUpdate.isRight()) {
1100 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set lifecycle for tosca elememt {} to state {}, error: {}", toscaElement.getUniqueId(), nextState, resultUpdate.right().value());
1101 result = Either.right(resultUpdate.right().value());
1104 if (result == null) {
1105 ToscaElementOperation operation = getToscaElementOperation(toscaElement.getLabel());
1106 result = operation.getToscaElement(toscaElement.getUniqueId());
1110 } catch (Exception e) {
1111 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during request certification tosca element {}. {}", toscaElementId, e.getMessage());
1116 private StorageOperationStatus handleRelationsUponForceCertification(GraphVertex toscaElement, GraphVertex modifier, GraphVertex owner) {
1118 StorageOperationStatus result = null;
1119 JanusGraphOperationStatus status = janusGraphDao
1120 .replaceEdgeLabel(owner.getVertex(), toscaElement.getVertex(), EdgeLabelEnum.STATE, EdgeLabelEnum.LAST_STATE);
1121 if (status != JanusGraphOperationStatus.OK) {
1122 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1124 if (result == null) {
1125 Map<EdgePropertyEnum, Object> properties = new EnumMap<>(EdgePropertyEnum.class);
1126 properties.put(EdgePropertyEnum.STATE, LifecycleStateEnum.CERTIFIED);
1127 status = janusGraphDao
1128 .createEdge(modifier, toscaElement, EdgeLabelEnum.STATE, properties);
1129 if (status != JanusGraphOperationStatus.OK) {
1130 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "failed to create edge. Status is {}", status);
1131 result = DaoStatusConverter.convertJanusGraphStatusToStorageStatus(status);
1134 if (result == null) {
1135 result = StorageOperationStatus.OK;
1140 private StorageOperationStatus updateEdgeToCatalogRootByUndoCheckout(JanusGraphVertex preV, GraphVertex curV) {
1142 return updateEdgeToCatalogRoot(null, curV);
1144 String uniqueIdPreVer = (String) janusGraphDao
1145 .getProperty((JanusGraphVertex) preV, GraphPropertyEnum.UNIQUE_ID.getProperty());
1146 LifecycleStateEnum state = LifecycleStateEnum.findState((String) janusGraphDao
1147 .getProperty(preV, GraphPropertyEnum.STATE.getProperty()));
1148 if (state == LifecycleStateEnum.CERTIFIED) {
1149 return updateEdgeToCatalogRoot(null, curV);
1151 return janusGraphDao.getVertexById(uniqueIdPreVer)
1152 .either(l -> updateEdgeToCatalogRoot(l, curV),
1153 DaoStatusConverter::convertJanusGraphStatusToStorageStatus);
1156 private StorageOperationStatus updateEdgeToCatalogRoot(GraphVertex newVersionV, GraphVertex prevVersionV) {
1157 Either<GraphVertex, JanusGraphOperationStatus> catalog = janusGraphDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
1158 if (catalog.isRight()) {
1159 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch catalog vertex. error {}", catalog.right().value());
1160 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(catalog.right().value());
1162 GraphVertex catalogV = catalog.left().value();
1163 if (newVersionV != null) {
1164 Boolean isAbstract = (Boolean) newVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1166 if ( isAbstract == null || !isAbstract ) {
1167 // no new vertex, only delete previous
1168 JanusGraphOperationStatus
1169 result = janusGraphDao
1170 .createEdge(catalogV, newVersionV, EdgeLabelEnum.CATALOG_ELEMENT, null);
1171 if (result != JanusGraphOperationStatus.OK) {
1172 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge from {} to catalog vertex. error {}", newVersionV.getUniqueId(), result);
1173 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(result);
1177 if (prevVersionV != null) {
1178 Boolean isAbstract = (Boolean) prevVersionV.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
1179 if (isAbstract == null || !isAbstract) {
1180 // if prev == null -> new resource was added
1181 Either<Edge, JanusGraphOperationStatus> deleteResult = janusGraphDao
1182 .deleteEdge(catalogV, prevVersionV, EdgeLabelEnum.CATALOG_ELEMENT);
1183 if (deleteResult.isRight()) {
1184 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to delete edge from {} to catalog vertex. error {}", prevVersionV.getUniqueId(), deleteResult.right().value());
1185 return DaoStatusConverter.convertJanusGraphStatusToStorageStatus(deleteResult.right().value());
1189 return StorageOperationStatus.OK;