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.lang.reflect.Type;
24 import java.util.ArrayList;
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.Iterator;
28 import java.util.List;
30 import java.util.Map.Entry;
33 import org.apache.tinkerpop.gremlin.structure.Direction;
34 import org.apache.tinkerpop.gremlin.structure.Edge;
35 import org.apache.tinkerpop.gremlin.structure.Vertex;
36 import org.openecomp.sdc.be.config.ConfigurationManager;
37 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
38 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
39 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
40 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
41 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
42 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
43 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
44 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
45 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
46 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
47 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
48 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
49 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
50 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
51 import org.openecomp.sdc.be.model.ComponentParametersView;
52 import org.openecomp.sdc.be.model.LifecycleStateEnum;
53 import org.openecomp.sdc.be.model.category.CategoryDefinition;
54 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
55 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
56 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
57 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
58 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
59 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
60 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
61 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
62 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
63 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
64 import org.openecomp.sdc.common.util.ValidationUtils;
65 import org.slf4j.Logger;
66 import org.slf4j.LoggerFactory;
67 import org.springframework.beans.factory.annotation.Autowired;
69 import com.google.gson.Gson;
70 import com.google.gson.reflect.TypeToken;
72 import fj.data.Either;
74 public abstract class ToscaElementOperation extends BaseOperation {
75 private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
77 private static final Gson gson = new Gson();
79 protected Gson getGson() {
84 protected CategoryOperation categoryOperation;
86 protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
88 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
89 propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
91 VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
92 Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
93 if (getResponse.isRight()) {
94 log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
95 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
98 List<GraphVertex> componentList = getResponse.left().value();
99 if (componentList.isEmpty()) {
100 log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
101 return Either.right(StorageOperationStatus.NOT_FOUND);
103 GraphVertex vertexG = componentList.get(0);
104 return Either.left(vertexG);
107 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
108 return getToscaElement(uniqueId, new ComponentParametersView());
111 public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
112 Either<GraphVertex, StorageOperationStatus> result = null;
114 Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
115 if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
116 // component already marked for delete
117 result = Either.left(componentToDelete);
121 componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
122 componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
124 Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
126 StorageOperationStatus updateComponent;
127 if (updateNode.isRight()) {
128 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
129 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
130 result = Either.right(updateComponent);
134 result = Either.left(componentToDelete);
140 * Performs a shadow clone of previousToscaElement
142 * @param previousToscaElement
143 * @param nextToscaElement
147 public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
149 Either<GraphVertex, StorageOperationStatus> result = null;
150 GraphVertex createdToscaElementVertex = null;
151 TitanOperationStatus status;
153 Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
154 if (createNextVersionRes.isRight()) {
155 status = createNextVersionRes.right().value();
156 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
157 previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
158 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
160 if (result == null) {
161 createdToscaElementVertex = createNextVersionRes.left().value();
162 Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
163 properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
164 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
165 if (status != TitanOperationStatus.OK) {
166 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.STATE, user.getUniqueId(),
167 previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
168 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
171 if (result == null) {
172 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
173 if (status != TitanOperationStatus.OK) {
174 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.LAST_MODIFIER, user.getUniqueId(),
175 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
176 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
179 if (result == null) {
180 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
181 if (status != TitanOperationStatus.OK) {
182 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from user vertex {} to tosca element vertex {} on graph. Status is {}. ", EdgeLabelEnum.CREATOR, user.getUniqueId(),
183 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
184 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
187 if (result == null) {
188 Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
189 while (edgesToCopyIter.hasNext()) {
190 Edge currEdge = edgesToCopyIter.next();
191 Vertex currVertex = currEdge.inVertex();
192 // if(EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()).equals(EdgeLabelEnum.VERSION)){
195 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
196 if (status != TitanOperationStatus.OK) {
197 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from tosca element vertex {} to vertex with label {} on graph. Status is {}. ", currEdge.label(), createdToscaElementVertex.getUniqueId(),
198 currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
199 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
205 if (result == null) {
206 result = Either.left(createdToscaElementVertex);
208 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
213 protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
214 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
215 if (parentVertex.isRight()) {
216 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
217 return parentVertex.right().value();
219 GraphVertex userV = parentVertex.left().value();
220 String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
221 toscaElement.setLastUpdaterUserId(userId);
222 toscaElement.setLastUpdaterFullName(buildFullName(userV));
223 return TitanOperationStatus.OK;
226 public String buildFullName(GraphVertex userV) {
228 String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
229 if (fullName == null) {
232 fullName = fullName + " ";
234 String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
235 if (lastName != null) {
236 fullName += lastName;
241 protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
242 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
243 if (parentVertex.isRight()) {
244 log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
245 return parentVertex.right().value();
247 GraphVertex userV = parentVertex.left().value();
248 String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
249 toscaElement.setCreatorUserId(creatorUserId);
250 toscaElement.setCreatorFullName(buildFullName(userV));
252 return TitanOperationStatus.OK;
255 protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
256 if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
257 toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
259 if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
260 toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
263 LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
264 if (lifecycleStateEnum == null) {
265 toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
267 long currentDate = System.currentTimeMillis();
268 if (toscaElement.getCreationDate() == null) {
269 toscaElement.setCreationDate(currentDate);
271 toscaElement.setLastUpdateDate(currentDate);
276 protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
277 if (toscaElement.isHighestVersion() == null) {
278 toscaElement.setHighestVersion(true);
280 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
281 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
282 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
283 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
284 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
285 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
286 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
287 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
288 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
289 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
290 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
291 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
292 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
293 toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
295 nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
296 nodeTypeVertex.setType(toscaElement.getComponentType());
300 protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
302 String userId = toscaElement.getCreatorUserId();
304 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
306 if (findUser.isRight()) {
307 TitanOperationStatus status = findUser.right().value();
308 log.error("Cannot find user {} in the graph. status is {}", userId, status);
309 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
312 GraphVertex creatorVertex = findUser.left().value();
313 GraphVertex updaterVertex = creatorVertex;
314 String updaterId = toscaElement.getLastUpdaterUserId();
315 if (updaterId != null && !updaterId.equals(userId)) {
316 findUser = findUserVertex(updaterId);
317 if (findUser.isRight()) {
318 TitanOperationStatus status = findUser.right().value();
319 log.error("Cannot find user {} in the graph. status is {}", userId, status);
320 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
322 updaterVertex = findUser.left().value();
325 Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
326 props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
328 TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
329 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
330 if (TitanOperationStatus.OK != result) {
331 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
333 result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
334 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
335 if (!result.equals(TitanOperationStatus.OK)) {
336 log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
337 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
340 toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
341 toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
343 result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
344 log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
345 if (!result.equals(TitanOperationStatus.OK)) {
346 log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
347 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
349 return StorageOperationStatus.OK;
352 protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
353 String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
354 String categoryName = nodeType.getCategories().get(0).getName();
355 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
357 if (getCategoryVertex.isRight()) {
358 return getCategoryVertex.right().value();
361 GraphVertex subCategoryV = getCategoryVertex.left().value();
363 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
364 if (createEdge != TitanOperationStatus.OK) {
365 log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
366 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
368 return StorageOperationStatus.OK;
371 protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
372 Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
373 if (category.isRight()) {
374 log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
375 return Either.right(category.right().value());
377 GraphVertex categoryV = category.left().value();
379 if (subcategoryName != null) {
380 Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
381 if (subCategory.isRight()) {
382 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
383 return Either.right(subCategory.right().value());
386 GraphVertex subCategoryV = subCategory.left().value();
387 return Either.left(subCategoryV);
389 return Either.left(categoryV);
392 private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
393 Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
394 Either<GraphVertex, StorageOperationStatus> status;
395 if (artifacts != null) {
396 artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
397 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
398 a.setUniqueId(uniqueId);
400 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
401 if (status.isRight()) {
402 return status.right().value();
405 Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
406 if (toscaArtifacts != null) {
407 toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
408 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
409 a.setUniqueId(uniqueId);
411 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
412 if (status.isRight()) {
413 return status.right().value();
416 Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
417 if (deploymentArtifacts != null) {
418 deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
419 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
420 a.setUniqueId(uniqueId);
422 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
423 if (status.isRight()) {
424 return status.right().value();
427 return StorageOperationStatus.OK;
430 protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
431 TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
432 if (status != TitanOperationStatus.OK) {
433 log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
436 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
437 if (status != TitanOperationStatus.OK) {
438 log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
441 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
442 if (status != TitanOperationStatus.OK) {
443 log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
446 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
447 if (status != TitanOperationStatus.OK) {
448 log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
451 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
452 if (status != TitanOperationStatus.OK) {
453 log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
456 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
457 if (status != TitanOperationStatus.OK) {
458 log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
461 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
462 if (status != TitanOperationStatus.OK) {
463 log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
466 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
467 if (status != TitanOperationStatus.OK) {
468 log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
471 return TitanOperationStatus.OK;
474 protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
476 StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
477 if (associateUsers != StorageOperationStatus.OK) {
478 return associateUsers;
480 StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
481 if (associateArtifacts != StorageOperationStatus.OK) {
482 return associateArtifacts;
484 StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
485 if (associateProperties != StorageOperationStatus.OK) {
486 return associateProperties;
488 StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
489 if (associateAdditionaInfo != StorageOperationStatus.OK) {
490 return associateAdditionaInfo;
493 return StorageOperationStatus.OK;
496 protected StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
497 // Note : currently only one derived supported!!!!
498 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.PROPERTIES);
499 if (dataFromDerived.isRight()) {
500 return dataFromDerived.right().value();
502 Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
504 Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
506 if (properties != null) {
507 properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
508 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
512 Either<Map<String, PropertyDataDefinition>, String> eitherMerged = ToscaDataDefinition.mergeDataMaps(propertiesAll, properties);
513 if (eitherMerged.isRight()) {
514 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
515 log.debug("property {} cannot be overriden", eitherMerged.right().value());
516 return StorageOperationStatus.INVALID_PROPERTY;
519 if (!propertiesAll.isEmpty()) {
520 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
521 if (assosiateElementToData.isRight()) {
522 return assosiateElementToData.right().value();
525 return StorageOperationStatus.OK;
528 private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
529 Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
530 if (additionalInformation != null) {
531 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
532 if (assosiateElementToData.isRight()) {
533 return assosiateElementToData.right().value();
536 return StorageOperationStatus.OK;
539 protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, EdgeLabelEnum edge) {
540 Map<String, T> propertiesAll = new HashMap<>();
542 if (derivedResources != null && !derivedResources.isEmpty()) {
543 for (GraphVertex derived : derivedResources) {
544 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
545 if (derivedProperties.isRight()) {
546 if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
547 log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
548 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
553 List<GraphVertex> propList = derivedProperties.left().value();
554 for (GraphVertex propV : propList) {
555 Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
556 if (propertiesFromDerived != null) {
557 propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
558 propertiesAll.putAll(propertiesFromDerived);
563 return Either.left(propertiesAll);
566 protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
567 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
568 if (result.isLeft()) {
569 toscaElement.setArtifacts(result.left().value());
571 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
572 return result.right().value();
575 result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
576 if (result.isLeft()) {
577 toscaElement.setDeploymentArtifacts(result.left().value());
579 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
580 return result.right().value();
583 result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
584 if (result.isLeft()) {
585 toscaElement.setToscaArtifacts(result.left().value());
587 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
588 return result.right().value();
591 return TitanOperationStatus.OK;
594 protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
595 Map<String, String> allVersion = new HashMap<>();
597 allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
598 ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
599 Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
600 while (childResourceRes.isLeft()) {
601 GraphVertex child = childResourceRes.left().value();
602 allChildrenAndParants.add(child);
603 childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
605 TitanOperationStatus operationStatus = childResourceRes.right().value();
607 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
608 return operationStatus;
610 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
611 while (parentResourceRes.isLeft()) {
612 GraphVertex parent = parentResourceRes.left().value();
613 allChildrenAndParants.add(parent);
614 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
616 operationStatus = parentResourceRes.right().value();
617 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
618 return operationStatus;
620 allChildrenAndParants.stream().filter(vertex -> {
621 Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
622 return (isDeleted == null || isDeleted == false);
623 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
625 toscaElement.setAllVersions(allVersion);
626 return TitanOperationStatus.OK;
631 protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
633 Either<List<T>, StorageOperationStatus> result = null;
635 Map<GraphPropertyEnum, Object> props = null;
637 if (userId != null) {
638 props = new HashMap<>();
639 // for Designer retrieve specific user
640 props.put(GraphPropertyEnum.USERID, userId);
642 // in case of user id == null -> get all users by label
643 // for Tester and Admin retrieve all users
644 Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
645 if (usersByCriteria.isRight()) {
646 log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
647 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
649 List<GraphVertex> users = usersByCriteria.left().value();
651 List<T> components = new ArrayList<>();
652 List<T> componentsPerUser;
653 for (GraphVertex userV : users) {
655 HashSet<String> ids = new HashSet<String>();
656 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
657 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
658 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
659 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
662 // get all resource with current state
663 if (childrenVertecies.isLeft()) {
664 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
666 if (componentsPerUser != null) {
667 for (T comp : componentsPerUser) {
668 ids.add(comp.getUniqueId());
669 components.add(comp);
673 if (lastStateStates != null && !lastStateStates.isEmpty()) {
674 // get all resource with last state
675 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_STATE, JsonParseFlagEnum.NoParse);
676 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
677 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.LAST_STATE, childrenVertecies.right().value());
678 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
680 if (childrenVertecies.isLeft()) {
682 componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
683 if (componentsPerUser != null) {
684 for (T comp : componentsPerUser) {
687 if (ids.contains(comp.getUniqueId())) {
690 if (isFirst == true) {
691 components.add(comp);
701 result = Either.left(components);
706 private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
707 List<T> components = new ArrayList<>();
708 for (GraphVertex node : vertices) {
710 Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
711 while (edges.hasNext()) {
712 Edge edge = edges.next();
713 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
715 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
716 if (nodeState == null) {
717 log.debug("no supported STATE {} for element {}", stateStr, node.getUniqueId());
720 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
722 Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
723 if (isDeleted != null && isDeleted) {
724 log.trace("Deleted element {}, discard", node.getUniqueId());
728 Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
731 ComponentTypeEnum componentType = node.getType();
732 // get only latest versions
734 if (componentType == null) {
735 log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
738 if (neededType == componentType) {
739 switch (componentType) {
742 handleNode(components, node, componentType);
745 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
746 if (isAbtract == null || false == isAbtract) {
747 handleNode(components, node, componentType);
751 log.debug("not supported node type {}", componentType);
762 protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
764 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
765 if (component.isRight()) {
766 log.debug("Failed to get component for id = {} error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
768 components.add(component.left().value());
772 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
773 Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
774 if (getVertexRes.isRight()) {
775 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
777 return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
780 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
782 log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
784 titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
786 T toscaElement = convertToComponent(vertexComponent);
788 TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
789 if (status != TitanOperationStatus.OK) {
790 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
793 status = setLastModifierFromGraph(vertexComponent, toscaElement);
794 if (status != TitanOperationStatus.OK) {
795 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
797 status = setCategoriesFromGraph(vertexComponent, toscaElement);
798 if (status != TitanOperationStatus.OK) {
799 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
801 if (!parametersFilter.isIgnoreAllVersions()) {
802 status = setAllVersions(vertexComponent, toscaElement);
803 if (status != TitanOperationStatus.OK) {
804 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
807 if (!parametersFilter.isIgnoreCapabilities()) {
808 status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
809 if (status != TitanOperationStatus.OK) {
810 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
813 if (!parametersFilter.isIgnoreRequirements()) {
814 status = setRequirementsFromGraph(vertexComponent, toscaElement);
815 if (status != TitanOperationStatus.OK) {
816 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
819 log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
820 return Either.left(toscaElement);
823 @SuppressWarnings("unchecked")
824 protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
825 ToscaElement toscaElement = null;
826 VertexTypeEnum label = componentV.getLabel();
829 toscaElement = new NodeType();
831 case TOPOLOGY_TEMPLATE:
832 toscaElement = new TopologyTemplate();
835 log.debug("Not supported tosca type {}", label);
839 Map<String, Object> jsonMetada = componentV.getMetadataJson();
840 if (toscaElement != null) {
841 toscaElement.setMetadata(jsonMetada);
843 return (T) toscaElement;
846 protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
847 List<CategoryDefinition> categories = new ArrayList<>();
848 SubCategoryDefinition subcategory;
850 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
851 if (childVertex.isRight()) {
852 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
853 return childVertex.right().value();
855 GraphVertex subCategoryV = childVertex.left().value();
856 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
857 subcategory = new SubCategoryDefinition();
858 subcategory.setUniqueId(subCategoryV.getUniqueId());
859 subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
860 subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
862 Type listTypeSubcat = new TypeToken<List<String>>() {
864 List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
865 subcategory.setIcons(iconsfromJsonSubcat);
867 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
868 if (parentVertex.isRight()) {
869 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
870 return childVertex.right().value();
872 GraphVertex categoryV = parentVertex.left().value();
873 metadataProperties = categoryV.getMetadataProperties();
875 CategoryDefinition category = new CategoryDefinition();
876 category.setUniqueId(categoryV.getUniqueId());
877 category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
878 category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
880 Type listTypeCat = new TypeToken<List<String>>() {
882 List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
883 category.setIcons(iconsfromJsonCat);
885 category.addSubCategory(subcategory);
886 categories.add(category);
887 toscaElement.setCategories(categories);
889 return TitanOperationStatus.OK;
892 public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
893 Either<T, StorageOperationStatus> result = null;
895 log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
896 if (toscaElementToUpdate == null) {
897 log.error("Service object is null");
898 result = Either.right(StorageOperationStatus.BAD_REQUEST);
902 String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
903 if (modifierUserId == null || modifierUserId.isEmpty()) {
904 log.error("UserId is missing in the request.");
905 result = Either.right(StorageOperationStatus.BAD_REQUEST);
908 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
910 if (findUser.isRight()) {
911 TitanOperationStatus status = findUser.right().value();
912 log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
916 GraphVertex modifierV = findUser.left().value();
917 // UserData modifierUserData = findUser.left().value();
918 String toscaElementId = toscaElementToUpdate.getUniqueId();
920 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
921 if (parentVertex.isRight()) {
922 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
923 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
925 GraphVertex userV = parentVertex.left().value();
926 String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
928 String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
930 if (currentModifier.equals(modifierUserId)) {
931 log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
933 log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
934 StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
935 log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
936 if (status != StorageOperationStatus.OK) {
937 result = Either.right(status);
942 final long currentTimeMillis = System.currentTimeMillis();
943 log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
944 elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
946 StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
947 if (checkCategories != StorageOperationStatus.OK) {
948 result = Either.right(checkCategories);
952 // update all data on vertex
953 fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
955 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
957 if (updateElement.isRight()) {
958 log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
959 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
962 GraphVertex updateElementV = updateElement.left().value();
964 // DE230195 in case resource name changed update TOSCA artifacts
965 // file names accordingly
966 String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
967 if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
968 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
969 if (resultToscaArt.isRight()) {
970 log.debug("Failed to get tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
971 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
974 Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
975 if (toscaArtifacts != null) {
976 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
977 generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
979 // TODO call to new Artifact operation in order to update list of artifacts
982 // US833308 VLI in service - specific network_role property value logic
983 if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
984 // update method logs success/error and returns boolean (true if nothing fails)
986 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
990 if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
991 StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
992 if (resultDerived != StorageOperationStatus.OK) {
993 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
994 return Either.right(resultDerived);
998 Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
999 if (updatedResource.isRight()) {
1000 log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
1001 result = Either.right(StorageOperationStatus.BAD_REQUEST);
1005 T updatedResourceValue = updatedResource.left().value();
1006 result = Either.left(updatedResourceValue);
1011 protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
1012 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
1015 protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
1016 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
1019 private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
1020 Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
1021 .findAny().get().getValue();
1022 artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
1025 protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1026 StorageOperationStatus status = StorageOperationStatus.OK;
1027 List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1028 CategoryDefinition newCategory = newCategoryList.get(0);
1030 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1031 if (childVertex.isRight()) {
1032 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1033 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1035 GraphVertex subCategoryV = childVertex.left().value();
1036 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1037 String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1039 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1040 if (parentVertex.isRight()) {
1041 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1042 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1044 GraphVertex categoryV = parentVertex.left().value();
1045 metadataProperties = categoryV.getMetadataProperties();
1046 String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1048 boolean categoryWasChanged = false;
1050 String newCategoryName = newCategory.getName();
1051 SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1052 String newSubCategoryName = newSubcategory.getName();
1053 if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1054 // the category was changed
1055 categoryWasChanged = true;
1057 // the sub-category was changed
1058 if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1059 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1060 categoryWasChanged = true;
1063 if (categoryWasChanged) {
1064 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1066 if (getCategoryVertex.isRight()) {
1067 return getCategoryVertex.right().value();
1069 GraphVertex newCategoryV = getCategoryVertex.left().value();
1070 status = moveCategoryEdge(elementV, newCategoryV);
1071 log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1076 public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, boolean isHighestVersions) {
1077 Either<List<GraphVertex>, TitanOperationStatus> listOfComponents;
1078 if (isHighestVersions) {
1079 listOfComponents = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.NoParse);
1082 listOfComponents = getListOfHighestAndAllCertifiedComponents(componentType, excludeTypes);
1085 if (listOfComponents.isRight() && listOfComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1086 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfComponents.right().value()));
1088 List<T> result = new ArrayList<>();
1089 if (listOfComponents.isLeft()) {
1090 List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
1091 if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1092 for (GraphVertex vertexComponent : highestAndAllCertified) {
1093 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1094 if (component.isRight()) {
1095 log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1096 return Either.right(component.right().value());
1098 result.add(component.left().value());
1103 return Either.left(result);
1106 private Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, JsonParseFlagEnum parseFlag) {
1107 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
1108 Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
1109 propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1110 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1112 if (componentType == ComponentTypeEnum.RESOURCE) {
1113 propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, false);
1114 propertiesHasNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1116 propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
1118 return titanDao.getByCriteria(null, propertiesToMatch, propertiesHasNotToMatch, parseFlag);
1121 // highest + (certified && !highest)
1122 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes) {
1123 long startFetchAllStates = System.currentTimeMillis();
1124 Either<List<GraphVertex>, TitanOperationStatus> highestNodes = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.ParseMetadata);
1126 Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1127 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1128 propertiesToMatchCertified.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1129 propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1130 if (componentType == ComponentTypeEnum.RESOURCE) {
1131 propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1132 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1135 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1136 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1138 Either<List<GraphVertex>, TitanOperationStatus> certifiedNotHighestNodes = titanDao.getByCriteria(null, propertiesToMatchCertified, propertiesHasNotToMatchCertified,
1139 JsonParseFlagEnum.ParseMetadata);
1140 if (certifiedNotHighestNodes.isRight() && certifiedNotHighestNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1141 return Either.right(certifiedNotHighestNodes.right().value());
1144 long endFetchAllStates = System.currentTimeMillis();
1146 List<GraphVertex> allNodes = new ArrayList<>();
1148 if (certifiedNotHighestNodes.isLeft()) {
1149 allNodes.addAll(certifiedNotHighestNodes.left().value());
1151 if (highestNodes.isLeft()) {
1152 allNodes.addAll(highestNodes.left().value());
1155 log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1156 return Either.left(allNodes);
1159 protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1161 // get all components marked for delete
1162 Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1163 props.put(GraphPropertyEnum.IS_DELETED, true);
1164 props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1166 Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1168 if (componentsToDelete.isRight()) {
1169 TitanOperationStatus error = componentsToDelete.right().value();
1170 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1171 log.trace("no components to delete");
1172 return Either.left(new ArrayList<>());
1174 log.info("failed to find components to delete. error : {}", error.name());
1175 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1178 return Either.left(componentsToDelete.left().value());
1181 protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1182 Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1183 if (result.isLeft()) {
1184 toscaElement.setAdditionalInformation(result.left().value());
1186 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1187 return result.right().value();
1190 return TitanOperationStatus.OK;
1193 // --------------------------------------------
1194 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1196 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1198 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1200 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1202 protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1204 protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1206 protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1208 protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1210 protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1212 public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);