1 package org.openecomp.sdc.be.model.jsontitan.operations;
3 import java.lang.reflect.Type;
4 import java.util.ArrayList;
5 import java.util.HashMap;
6 import java.util.HashSet;
7 import java.util.Iterator;
10 import java.util.Map.Entry;
13 import org.apache.tinkerpop.gremlin.structure.Direction;
14 import org.apache.tinkerpop.gremlin.structure.Edge;
15 import org.apache.tinkerpop.gremlin.structure.Vertex;
16 import org.openecomp.sdc.be.config.ConfigurationManager;
17 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
18 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
19 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
20 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
21 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
22 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
23 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
24 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
25 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
26 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
27 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
28 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
29 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
30 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
31 import org.openecomp.sdc.be.model.ComponentParametersView;
32 import org.openecomp.sdc.be.model.LifecycleStateEnum;
33 import org.openecomp.sdc.be.model.category.CategoryDefinition;
34 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
35 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
36 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
37 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
38 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
39 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
40 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
41 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
42 import org.openecomp.sdc.be.resources.data.UserData;
43 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
44 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
45 import org.openecomp.sdc.common.util.ValidationUtils;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
48 import org.springframework.beans.factory.annotation.Autowired;
50 import com.google.gson.Gson;
51 import com.google.gson.reflect.TypeToken;
53 import fj.data.Either;
55 public abstract class ToscaElementOperation extends BaseOperation {
56 private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
58 private static final Gson gson = new Gson();
60 protected Gson getGson() {
65 protected CategoryOperation categoryOperation;
67 protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
69 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
70 propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
72 VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
73 Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
74 if (getResponse.isRight()) {
75 log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
76 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
79 List<GraphVertex> componentList = getResponse.left().value();
80 if (componentList.isEmpty()) {
81 log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
82 return Either.right(StorageOperationStatus.NOT_FOUND);
84 GraphVertex vertexG = componentList.get(0);
85 return Either.left(vertexG);
88 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
89 return getToscaElement(uniqueId, new ComponentParametersView());
92 public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
93 Either<GraphVertex, StorageOperationStatus> result = null;
95 Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
96 if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
97 // component already marked for delete
98 result = Either.left(componentToDelete);
102 componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
103 componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
105 Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
107 StorageOperationStatus updateComponent;
108 if (updateNode.isRight()) {
109 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
110 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
111 result = Either.right(updateComponent);
115 result = Either.left(componentToDelete);
121 * Performs a shadow clone of previousToscaElement
123 * @param previousToscaElement
124 * @param nextToscaElement
128 public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
130 Either<GraphVertex, StorageOperationStatus> result = null;
131 GraphVertex createdToscaElementVertex = null;
132 TitanOperationStatus status;
134 Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
135 if (createNextVersionRes.isRight()) {
136 status = createNextVersionRes.right().value();
137 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
138 previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
139 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
141 if (result == null) {
142 createdToscaElementVertex = createNextVersionRes.left().value();
143 Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
144 properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
145 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
146 if (status != TitanOperationStatus.OK) {
147 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(),
148 previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
149 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
152 if (result == null) {
153 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
154 if (status != TitanOperationStatus.OK) {
155 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(),
156 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
157 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
160 if (result == null) {
161 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
162 if (status != TitanOperationStatus.OK) {
163 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(),
164 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
165 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
168 if (result == null) {
169 Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
170 while (edgesToCopyIter.hasNext()) {
171 Edge currEdge = edgesToCopyIter.next();
172 Vertex currVertex = currEdge.inVertex();
173 // if(EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()).equals(EdgeLabelEnum.VERSION)){
176 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
177 if (status != TitanOperationStatus.OK) {
178 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(),
179 currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
180 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
186 if (result == null) {
187 result = Either.left(createdToscaElementVertex);
189 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
194 protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
195 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
196 if (parentVertex.isRight()) {
197 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
198 return parentVertex.right().value();
200 GraphVertex userV = parentVertex.left().value();
201 String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
202 toscaElement.setLastUpdaterUserId(userId);
203 toscaElement.setLastUpdaterFullName(buildFullName(userV));
204 return TitanOperationStatus.OK;
207 public String buildFullName(GraphVertex userV) {
209 String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
210 if (fullName == null) {
213 fullName = fullName + " ";
215 String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
216 if (lastName != null) {
217 fullName += lastName;
222 protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
223 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
224 if (parentVertex.isRight()) {
225 log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
226 return parentVertex.right().value();
228 GraphVertex userV = parentVertex.left().value();
229 String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
230 toscaElement.setCreatorUserId(creatorUserId);
231 toscaElement.setCreatorFullName(buildFullName(userV));
233 return TitanOperationStatus.OK;
236 protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
237 if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
238 toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
240 if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
241 toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
244 LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
245 if (lifecycleStateEnum == null) {
246 toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
248 long currentDate = System.currentTimeMillis();
249 if (toscaElement.getCreationDate() == null) {
250 toscaElement.setCreationDate(currentDate);
252 toscaElement.setLastUpdateDate(currentDate);
257 protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
258 if (toscaElement.isHighestVersion() == null) {
259 toscaElement.setHighestVersion(true);
261 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
262 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
263 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
264 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
265 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
266 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
267 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
268 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
269 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
270 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
271 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
272 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
273 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
274 toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
276 nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
277 nodeTypeVertex.setType(toscaElement.getComponentType());
281 protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
283 String userId = toscaElement.getCreatorUserId();
285 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
287 if (findUser.isRight()) {
288 TitanOperationStatus status = findUser.right().value();
289 log.error("Cannot find user {} in the graph. status is {}", userId, status);
290 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
293 GraphVertex creatorVertex = findUser.left().value();
294 GraphVertex updaterVertex = creatorVertex;
295 String updaterId = toscaElement.getLastUpdaterUserId();
296 if (updaterId != null && !updaterId.equals(userId)) {
297 findUser = findUserVertex(updaterId);
298 if (findUser.isRight()) {
299 TitanOperationStatus status = findUser.right().value();
300 log.error("Cannot find user {} in the graph. status is {}", userId, status);
301 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
303 updaterVertex = findUser.left().value();
306 Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
307 props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
309 TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
310 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
311 if (TitanOperationStatus.OK != result) {
312 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
314 result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
315 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
316 if (!result.equals(TitanOperationStatus.OK)) {
317 log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
318 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
321 toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
322 toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
324 result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
325 log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
326 if (!result.equals(TitanOperationStatus.OK)) {
327 log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
328 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
330 return StorageOperationStatus.OK;
333 protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
334 String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
335 String categoryName = nodeType.getCategories().get(0).getName();
336 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
338 if (getCategoryVertex.isRight()) {
339 return getCategoryVertex.right().value();
342 GraphVertex subCategoryV = getCategoryVertex.left().value();
344 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
345 if (createEdge != TitanOperationStatus.OK) {
346 log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
347 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
349 return StorageOperationStatus.OK;
352 protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
353 Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
354 if (category.isRight()) {
355 log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
356 return Either.right(category.right().value());
358 GraphVertex categoryV = category.left().value();
360 if (subcategoryName != null) {
361 Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
362 if (subCategory.isRight()) {
363 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
364 return Either.right(subCategory.right().value());
367 GraphVertex subCategoryV = subCategory.left().value();
368 return Either.left(subCategoryV);
370 return Either.left(categoryV);
373 private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
374 Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
375 Either<GraphVertex, StorageOperationStatus> status;
376 if (artifacts != null) {
377 artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
378 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
379 a.setUniqueId(uniqueId);
381 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
382 if (status.isRight()) {
383 return status.right().value();
386 Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
387 if (toscaArtifacts != null) {
388 toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
389 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
390 a.setUniqueId(uniqueId);
392 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
393 if (status.isRight()) {
394 return status.right().value();
397 Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
398 if (deploymentArtifacts != null) {
399 deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
400 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
401 a.setUniqueId(uniqueId);
403 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
404 if (status.isRight()) {
405 return status.right().value();
408 return StorageOperationStatus.OK;
411 protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
412 TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
413 if (status != TitanOperationStatus.OK) {
414 log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
417 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
418 if (status != TitanOperationStatus.OK) {
419 log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
422 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
423 if (status != TitanOperationStatus.OK) {
424 log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
427 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
428 if (status != TitanOperationStatus.OK) {
429 log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
432 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
433 if (status != TitanOperationStatus.OK) {
434 log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
437 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
438 if (status != TitanOperationStatus.OK) {
439 log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
442 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
443 if (status != TitanOperationStatus.OK) {
444 log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
447 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
448 if (status != TitanOperationStatus.OK) {
449 log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
452 return TitanOperationStatus.OK;
455 protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
457 StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
458 if (associateUsers != StorageOperationStatus.OK) {
459 return associateUsers;
461 StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
462 if (associateArtifacts != StorageOperationStatus.OK) {
463 return associateArtifacts;
465 StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
466 if (associateProperties != StorageOperationStatus.OK) {
467 return associateProperties;
469 StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
470 if (associateAdditionaInfo != StorageOperationStatus.OK) {
471 return associateAdditionaInfo;
474 return StorageOperationStatus.OK;
477 protected StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
478 // Note : currently only one derived supported!!!!
479 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.PROPERTIES);
480 if (dataFromDerived.isRight()) {
481 return dataFromDerived.right().value();
483 Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
485 Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
487 if (properties != null) {
488 properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
489 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
493 Either<Map<String, PropertyDataDefinition>, String> eitherMerged = ToscaDataDefinition.mergeDataMaps(propertiesAll, properties);
494 if (eitherMerged.isRight()) {
495 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
496 log.debug("property {} cannot be overriden", eitherMerged.right().value());
497 return StorageOperationStatus.INVALID_PROPERTY;
500 if (!propertiesAll.isEmpty()) {
501 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
502 if (assosiateElementToData.isRight()) {
503 return assosiateElementToData.right().value();
506 return StorageOperationStatus.OK;
509 private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
510 Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
511 if (additionalInformation != null) {
512 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
513 if (assosiateElementToData.isRight()) {
514 return assosiateElementToData.right().value();
517 return StorageOperationStatus.OK;
520 protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, EdgeLabelEnum edge) {
521 Map<String, T> propertiesAll = new HashMap<>();
523 if (derivedResources != null && !derivedResources.isEmpty()) {
524 for (GraphVertex derived : derivedResources) {
525 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
526 if (derivedProperties.isRight()) {
527 if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
528 log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
529 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
534 List<GraphVertex> propList = derivedProperties.left().value();
535 for (GraphVertex propV : propList) {
536 Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
537 if (propertiesFromDerived != null) {
538 propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
539 propertiesAll.putAll(propertiesFromDerived);
544 return Either.left(propertiesAll);
547 protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
548 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
549 if (result.isLeft()) {
550 toscaElement.setArtifacts(result.left().value());
552 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
553 return result.right().value();
556 result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
557 if (result.isLeft()) {
558 toscaElement.setDeploymentArtifacts(result.left().value());
560 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
561 return result.right().value();
564 result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
565 if (result.isLeft()) {
566 toscaElement.setToscaArtifacts(result.left().value());
568 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
569 return result.right().value();
572 return TitanOperationStatus.OK;
575 protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
576 Map<String, String> allVersion = new HashMap<>();
578 allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
579 ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
580 Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
581 while (childResourceRes.isLeft()) {
582 GraphVertex child = childResourceRes.left().value();
583 allChildrenAndParants.add(child);
584 childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
586 TitanOperationStatus operationStatus = childResourceRes.right().value();
588 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
589 return operationStatus;
591 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
592 while (parentResourceRes.isLeft()) {
593 GraphVertex parent = parentResourceRes.left().value();
594 allChildrenAndParants.add(parent);
595 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
597 operationStatus = parentResourceRes.right().value();
598 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
599 return operationStatus;
601 allChildrenAndParants.stream().filter(vertex -> {
602 Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
603 return (isDeleted == null || isDeleted == false);
604 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
606 toscaElement.setAllVersions(allVersion);
607 return TitanOperationStatus.OK;
612 protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
614 Either<List<T>, StorageOperationStatus> result = null;
616 Map<GraphPropertyEnum, Object> props = null;
618 if (userId != null) {
619 props = new HashMap<>();
620 // for Designer retrieve specific user
621 props.put(GraphPropertyEnum.USERID, userId);
623 // in case of user id == null -> get all users by label
624 // for Tester and Admin retrieve all users
625 Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
626 if (usersByCriteria.isRight()) {
627 log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
628 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
630 List<GraphVertex> users = usersByCriteria.left().value();
632 List<T> components = new ArrayList<>();
633 List<T> componentsPerUser;
634 for (GraphVertex userV : users) {
636 HashSet<String> ids = new HashSet<String>();
637 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
638 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
639 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
640 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
643 // get all resource with current state
644 if (childrenVertecies.isLeft()) {
645 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
647 if (componentsPerUser != null) {
648 for (T comp : componentsPerUser) {
649 ids.add(comp.getUniqueId());
650 components.add(comp);
654 if (lastStateStates != null && !lastStateStates.isEmpty()) {
655 // get all resource with last state
656 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_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.LAST_STATE, childrenVertecies.right().value());
659 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
661 if (childrenVertecies.isLeft()) {
663 componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
664 if (componentsPerUser != null) {
665 for (T comp : componentsPerUser) {
668 if (ids.contains(comp.getUniqueId())) {
671 if (isFirst == true) {
672 components.add(comp);
682 result = Either.left(components);
687 private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
688 List<T> components = new ArrayList<>();
689 for (GraphVertex node : vertices) {
691 Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
692 while (edges.hasNext()) {
693 Edge edge = edges.next();
694 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
696 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
697 if (nodeState == null) {
698 log.debug("no supported STATE {} for element {}", stateStr, node.getUniqueId());
701 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
703 Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
704 if (isDeleted != null && isDeleted) {
705 log.trace("Deleted element {}, discard", node.getUniqueId());
709 Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
712 ComponentTypeEnum componentType = node.getType();
713 // get only latest versions
715 if (componentType == null) {
716 log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
719 if (neededType == componentType) {
720 switch (componentType) {
723 handleNode(components, node, componentType);
726 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
727 if (isAbtract == null || false == isAbtract) {
728 handleNode(components, node, componentType);
732 log.debug("not supported node type {}", componentType);
743 protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
745 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
746 if (component.isRight()) {
747 log.debug("Failed to get component for id = {} error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
749 components.add(component.left().value());
753 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
754 Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
755 if (getVertexRes.isRight()) {
756 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
758 return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
761 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
763 log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
765 titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
767 T toscaElement = convertToComponent(vertexComponent);
769 TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
770 if (status != TitanOperationStatus.OK) {
771 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
774 status = setLastModifierFromGraph(vertexComponent, toscaElement);
775 if (status != TitanOperationStatus.OK) {
776 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
778 status = setCategoriesFromGraph(vertexComponent, toscaElement);
779 if (status != TitanOperationStatus.OK) {
780 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
782 if (!parametersFilter.isIgnoreAllVersions()) {
783 status = setAllVersions(vertexComponent, toscaElement);
784 if (status != TitanOperationStatus.OK) {
785 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
788 if (!parametersFilter.isIgnoreCapabilities()) {
789 status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
790 if (status != TitanOperationStatus.OK) {
791 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
794 if (!parametersFilter.isIgnoreRequirements()) {
795 status = setRequirementsFromGraph(vertexComponent, toscaElement);
796 if (status != TitanOperationStatus.OK) {
797 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
800 log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
801 return Either.left(toscaElement);
804 @SuppressWarnings("unchecked")
805 protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
806 ToscaElement toscaElement = null;
807 VertexTypeEnum label = componentV.getLabel();
810 toscaElement = new NodeType();
812 case TOPOLOGY_TEMPLATE:
813 toscaElement = new TopologyTemplate();
816 log.debug("Not supported tosca type {}", label);
820 Map<String, Object> jsonMetada = componentV.getMetadataJson();
821 if (toscaElement != null) {
822 toscaElement.setMetadata(jsonMetada);
824 return (T) toscaElement;
827 protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
828 List<CategoryDefinition> categories = new ArrayList<>();
829 SubCategoryDefinition subcategory;
831 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
832 if (childVertex.isRight()) {
833 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
834 return childVertex.right().value();
836 GraphVertex subCategoryV = childVertex.left().value();
837 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
838 subcategory = new SubCategoryDefinition();
839 subcategory.setUniqueId(subCategoryV.getUniqueId());
840 subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
841 subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
843 Type listTypeSubcat = new TypeToken<List<String>>() {
845 List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
846 subcategory.setIcons(iconsfromJsonSubcat);
848 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
849 if (parentVertex.isRight()) {
850 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
851 return childVertex.right().value();
853 GraphVertex categoryV = parentVertex.left().value();
854 metadataProperties = categoryV.getMetadataProperties();
856 CategoryDefinition category = new CategoryDefinition();
857 category.setUniqueId(categoryV.getUniqueId());
858 category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
859 category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
861 Type listTypeCat = new TypeToken<List<String>>() {
863 List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
864 category.setIcons(iconsfromJsonCat);
866 category.addSubCategory(subcategory);
867 categories.add(category);
868 toscaElement.setCategories(categories);
870 return TitanOperationStatus.OK;
873 public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
874 Either<T, StorageOperationStatus> result = null;
876 log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
877 if (toscaElementToUpdate == null) {
878 log.error("Service object is null");
879 result = Either.right(StorageOperationStatus.BAD_REQUEST);
883 String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
884 if (modifierUserId == null || modifierUserId.isEmpty()) {
885 log.error("UserId is missing in the request.");
886 result = Either.right(StorageOperationStatus.BAD_REQUEST);
889 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
891 if (findUser.isRight()) {
892 TitanOperationStatus status = findUser.right().value();
893 log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
897 GraphVertex modifierV = findUser.left().value();
898 // UserData modifierUserData = findUser.left().value();
899 String toscaElementId = toscaElementToUpdate.getUniqueId();
901 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
902 if (parentVertex.isRight()) {
903 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
904 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
906 GraphVertex userV = parentVertex.left().value();
907 String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
909 String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
911 if (currentModifier.equals(modifierUserId)) {
912 log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
914 log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
915 StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
916 log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
917 if (status != StorageOperationStatus.OK) {
918 result = Either.right(status);
923 final long currentTimeMillis = System.currentTimeMillis();
924 log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
925 elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
927 StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
928 if (checkCategories != StorageOperationStatus.OK) {
929 result = Either.right(checkCategories);
933 // update all data on vertex
934 fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
936 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
938 if (updateElement.isRight()) {
939 log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
940 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
943 GraphVertex updateElementV = updateElement.left().value();
945 // DE230195 in case resource name changed update TOSCA artifacts
946 // file names accordingly
947 String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
948 if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
949 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
950 if (resultToscaArt.isRight()) {
951 log.debug("Failed to get tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
952 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
955 Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
956 if (toscaArtifacts != null) {
957 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
958 generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
960 // TODO call to new Artifact operation in order to update list of artifacts
963 // US833308 VLI in service - specific network_role property value logic
964 if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
965 // update method logs success/error and returns boolean (true if nothing fails)
967 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
971 if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
972 StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
973 if (resultDerived != StorageOperationStatus.OK) {
974 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
975 return Either.right(resultDerived);
979 Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
980 if (updatedResource.isRight()) {
981 log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
982 result = Either.right(StorageOperationStatus.BAD_REQUEST);
986 T updatedResourceValue = updatedResource.left().value();
987 result = Either.left(updatedResourceValue);
992 protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
993 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
996 protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
997 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
1000 private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
1001 Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
1002 .findAny().get().getValue();
1003 artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
1006 protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1007 StorageOperationStatus status = StorageOperationStatus.OK;
1008 List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1009 CategoryDefinition newCategory = newCategoryList.get(0);
1011 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1012 if (childVertex.isRight()) {
1013 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1014 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1016 GraphVertex subCategoryV = childVertex.left().value();
1017 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1018 String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1020 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1021 if (parentVertex.isRight()) {
1022 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1023 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1025 GraphVertex categoryV = parentVertex.left().value();
1026 metadataProperties = categoryV.getMetadataProperties();
1027 String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1029 boolean categoryWasChanged = false;
1031 String newCategoryName = newCategory.getName();
1032 SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1033 String newSubCategoryName = newSubcategory.getName();
1034 if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1035 // the category was changed
1036 categoryWasChanged = true;
1038 // the sub-category was changed
1039 if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1040 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1041 categoryWasChanged = true;
1044 if (categoryWasChanged) {
1045 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1047 if (getCategoryVertex.isRight()) {
1048 return getCategoryVertex.right().value();
1050 GraphVertex newCategoryV = getCategoryVertex.left().value();
1051 status = moveCategoryEdge(elementV, newCategoryV);
1052 log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1057 public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement, boolean isHighestVersions) {
1058 Either<List<GraphVertex>, TitanOperationStatus> listOfComponents;
1059 if (isHighestVersions) {
1060 listOfComponents = getListOfHighestComponents(componentType, toscaElement);
1062 listOfComponents = getListOfHighestAndAllCertifiedComponents(componentType, toscaElement);
1064 if (listOfComponents.isRight() && listOfComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1065 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfComponents.right().value()));
1067 List<T> result = new ArrayList<>();
1068 if (listOfComponents.isLeft()) {
1069 List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
1070 if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1071 for (GraphVertex vertexComponent : highestAndAllCertified) {
1072 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1073 if (component.isRight()) {
1074 log.debug("Failed to fetch ligth element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1075 return Either.right(component.right().value());
1077 result.add(component.left().value());
1082 return Either.left(result);
1085 private Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement) {
1086 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
1087 propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1088 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1090 if (componentType == ComponentTypeEnum.RESOURCE) {
1091 propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, false);
1094 Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
1095 propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
1097 return titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatch, propertiesHasNotToMatch, JsonParseFlagEnum.ParseMetadata);
1100 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement) {
1101 long startFetchAllStates = System.currentTimeMillis();
1102 Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1103 propertiesToMatchCertified.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1104 propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1105 if (componentType == ComponentTypeEnum.RESOURCE) {
1106 propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1109 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1110 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1112 Either<List<GraphVertex>, TitanOperationStatus> certifiedNodes = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatchCertified, propertiesHasNotToMatchCertified,
1113 JsonParseFlagEnum.ParseMetadata);
1114 if (certifiedNodes.isRight() && certifiedNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1115 return Either.right(certifiedNodes.right().value());
1118 Map<GraphPropertyEnum, Object> propertiesToMatchHighest = new HashMap<>();
1119 propertiesToMatchHighest.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1120 propertiesToMatchHighest.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1121 if (componentType == ComponentTypeEnum.RESOURCE) {
1122 propertiesToMatchHighest.put(GraphPropertyEnum.IS_ABSTRACT, false);
1125 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchHighest = new HashMap<>();
1126 propertiesHasNotToMatchHighest.put(GraphPropertyEnum.IS_DELETED, true);
1127 propertiesHasNotToMatchHighest.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1129 Either<List<GraphVertex>, TitanOperationStatus> highestNode = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatchHighest, propertiesHasNotToMatchHighest, JsonParseFlagEnum.ParseMetadata);
1130 if (highestNode.isRight() && highestNode.right().value() != TitanOperationStatus.NOT_FOUND) {
1131 return Either.right(highestNode.right().value());
1134 long endFetchAllStates = System.currentTimeMillis();
1136 List<GraphVertex> allNodes = new ArrayList<>();
1138 if (certifiedNodes.isLeft()) {
1139 allNodes.addAll(certifiedNodes.left().value());
1141 if (highestNode.isLeft()) {
1142 allNodes.addAll(highestNode.left().value());
1146 int nonCertifiedSize;
1148 if (certifiedNodes.isRight()) {
1151 certifiedSize = certifiedNodes.left().value().size();
1154 if (highestNode.isRight()) {
1155 nonCertifiedSize = 0;
1157 nonCertifiedSize = highestNode.left().value().size();
1160 log.debug("Fetch catalog {}s all states: certified {}, noncertified {}", componentType, certifiedSize, nonCertifiedSize);
1161 log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1162 return Either.left(allNodes);
1165 protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1167 // get all components marked for delete
1168 Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1169 props.put(GraphPropertyEnum.IS_DELETED, true);
1170 props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1172 Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1174 if (componentsToDelete.isRight()) {
1175 TitanOperationStatus error = componentsToDelete.right().value();
1176 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1177 log.trace("no components to delete");
1178 return Either.left(new ArrayList<>());
1180 log.info("failed to find components to delete. error : {}", error.name());
1181 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1184 return Either.left(componentsToDelete.left().value());
1187 protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1188 Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1189 if (result.isLeft()) {
1190 toscaElement.setAdditionalInformation(result.left().value());
1192 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1193 return result.right().value();
1196 return TitanOperationStatus.OK;
1199 // --------------------------------------------
1200 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1202 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1204 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1206 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1208 protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1210 protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1212 protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1214 protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1216 protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1218 public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);