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.be.resources.data.UserData;
63 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
64 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
65 import org.openecomp.sdc.common.util.ValidationUtils;
66 import org.slf4j.Logger;
67 import org.slf4j.LoggerFactory;
68 import org.springframework.beans.factory.annotation.Autowired;
70 import com.google.gson.Gson;
71 import com.google.gson.reflect.TypeToken;
73 import fj.data.Either;
75 public abstract class ToscaElementOperation extends BaseOperation {
76 private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
78 private static final Gson gson = new Gson();
80 protected Gson getGson() {
85 protected CategoryOperation categoryOperation;
87 protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
89 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
90 propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
92 VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
93 Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
94 if (getResponse.isRight()) {
95 log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
96 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
99 List<GraphVertex> componentList = getResponse.left().value();
100 if (componentList.isEmpty()) {
101 log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
102 return Either.right(StorageOperationStatus.NOT_FOUND);
104 GraphVertex vertexG = componentList.get(0);
105 return Either.left(vertexG);
108 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
109 return getToscaElement(uniqueId, new ComponentParametersView());
112 public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
113 Either<GraphVertex, StorageOperationStatus> result = null;
115 Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
116 if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
117 // component already marked for delete
118 result = Either.left(componentToDelete);
122 componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
123 componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
125 Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
127 StorageOperationStatus updateComponent;
128 if (updateNode.isRight()) {
129 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
130 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
131 result = Either.right(updateComponent);
135 result = Either.left(componentToDelete);
141 * Performs a shadow clone of previousToscaElement
143 * @param previousToscaElement
144 * @param nextToscaElement
148 public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
150 Either<GraphVertex, StorageOperationStatus> result = null;
151 GraphVertex createdToscaElementVertex = null;
152 TitanOperationStatus status;
154 Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
155 if (createNextVersionRes.isRight()) {
156 status = createNextVersionRes.right().value();
157 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
158 previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
159 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
161 if (result == null) {
162 createdToscaElementVertex = createNextVersionRes.left().value();
163 Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
164 properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
165 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
166 if (status != TitanOperationStatus.OK) {
167 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(),
168 previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
169 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
172 if (result == null) {
173 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
174 if (status != TitanOperationStatus.OK) {
175 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(),
176 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
177 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
180 if (result == null) {
181 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
182 if (status != TitanOperationStatus.OK) {
183 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(),
184 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
185 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
188 if (result == null) {
189 Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
190 while (edgesToCopyIter.hasNext()) {
191 Edge currEdge = edgesToCopyIter.next();
192 Vertex currVertex = currEdge.inVertex();
193 // if(EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()).equals(EdgeLabelEnum.VERSION)){
196 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
197 if (status != TitanOperationStatus.OK) {
198 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(),
199 currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
200 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
206 if (result == null) {
207 result = Either.left(createdToscaElementVertex);
209 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
214 protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
215 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
216 if (parentVertex.isRight()) {
217 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
218 return parentVertex.right().value();
220 GraphVertex userV = parentVertex.left().value();
221 String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
222 toscaElement.setLastUpdaterUserId(userId);
223 toscaElement.setLastUpdaterFullName(buildFullName(userV));
224 return TitanOperationStatus.OK;
227 public String buildFullName(GraphVertex userV) {
229 String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
230 if (fullName == null) {
233 fullName = fullName + " ";
235 String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
236 if (lastName != null) {
237 fullName += lastName;
242 protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
243 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
244 if (parentVertex.isRight()) {
245 log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
246 return parentVertex.right().value();
248 GraphVertex userV = parentVertex.left().value();
249 String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
250 toscaElement.setCreatorUserId(creatorUserId);
251 toscaElement.setCreatorFullName(buildFullName(userV));
253 return TitanOperationStatus.OK;
256 protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
257 if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
258 toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
260 if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
261 toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
264 LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
265 if (lifecycleStateEnum == null) {
266 toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
268 long currentDate = System.currentTimeMillis();
269 if (toscaElement.getCreationDate() == null) {
270 toscaElement.setCreationDate(currentDate);
272 toscaElement.setLastUpdateDate(currentDate);
277 protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
278 if (toscaElement.isHighestVersion() == null) {
279 toscaElement.setHighestVersion(true);
281 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
282 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
283 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
284 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
285 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
286 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
287 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
288 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
289 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
290 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
291 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
292 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
293 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
294 toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
296 nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
297 nodeTypeVertex.setType(toscaElement.getComponentType());
301 protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
303 String userId = toscaElement.getCreatorUserId();
305 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
307 if (findUser.isRight()) {
308 TitanOperationStatus status = findUser.right().value();
309 log.error("Cannot find user {} in the graph. status is {}", userId, status);
310 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
313 GraphVertex creatorVertex = findUser.left().value();
314 GraphVertex updaterVertex = creatorVertex;
315 String updaterId = toscaElement.getLastUpdaterUserId();
316 if (updaterId != null && !updaterId.equals(userId)) {
317 findUser = findUserVertex(updaterId);
318 if (findUser.isRight()) {
319 TitanOperationStatus status = findUser.right().value();
320 log.error("Cannot find user {} in the graph. status is {}", userId, status);
321 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
323 updaterVertex = findUser.left().value();
326 Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
327 props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
329 TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
330 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
331 if (TitanOperationStatus.OK != result) {
332 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
334 result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
335 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
336 if (!result.equals(TitanOperationStatus.OK)) {
337 log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
338 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
341 toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
342 toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
344 result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
345 log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
346 if (!result.equals(TitanOperationStatus.OK)) {
347 log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
348 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
350 return StorageOperationStatus.OK;
353 protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
354 String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
355 String categoryName = nodeType.getCategories().get(0).getName();
356 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
358 if (getCategoryVertex.isRight()) {
359 return getCategoryVertex.right().value();
362 GraphVertex subCategoryV = getCategoryVertex.left().value();
364 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
365 if (createEdge != TitanOperationStatus.OK) {
366 log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
367 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
369 return StorageOperationStatus.OK;
372 protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
373 Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
374 if (category.isRight()) {
375 log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
376 return Either.right(category.right().value());
378 GraphVertex categoryV = category.left().value();
380 if (subcategoryName != null) {
381 Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
382 if (subCategory.isRight()) {
383 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
384 return Either.right(subCategory.right().value());
387 GraphVertex subCategoryV = subCategory.left().value();
388 return Either.left(subCategoryV);
390 return Either.left(categoryV);
393 private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
394 Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
395 Either<GraphVertex, StorageOperationStatus> status;
396 if (artifacts != null) {
397 artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
398 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
399 a.setUniqueId(uniqueId);
401 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
402 if (status.isRight()) {
403 return status.right().value();
406 Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
407 if (toscaArtifacts != null) {
408 toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
409 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
410 a.setUniqueId(uniqueId);
412 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
413 if (status.isRight()) {
414 return status.right().value();
417 Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
418 if (deploymentArtifacts != null) {
419 deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
420 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
421 a.setUniqueId(uniqueId);
423 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
424 if (status.isRight()) {
425 return status.right().value();
428 return StorageOperationStatus.OK;
431 protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
432 TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
433 if (status != TitanOperationStatus.OK) {
434 log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
437 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
438 if (status != TitanOperationStatus.OK) {
439 log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
442 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
443 if (status != TitanOperationStatus.OK) {
444 log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
447 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
448 if (status != TitanOperationStatus.OK) {
449 log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
452 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
453 if (status != TitanOperationStatus.OK) {
454 log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
457 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
458 if (status != TitanOperationStatus.OK) {
459 log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
462 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
463 if (status != TitanOperationStatus.OK) {
464 log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
467 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
468 if (status != TitanOperationStatus.OK) {
469 log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
472 return TitanOperationStatus.OK;
475 protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
477 StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
478 if (associateUsers != StorageOperationStatus.OK) {
479 return associateUsers;
481 StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
482 if (associateArtifacts != StorageOperationStatus.OK) {
483 return associateArtifacts;
485 StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
486 if (associateProperties != StorageOperationStatus.OK) {
487 return associateProperties;
489 StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
490 if (associateAdditionaInfo != StorageOperationStatus.OK) {
491 return associateAdditionaInfo;
494 return StorageOperationStatus.OK;
497 protected StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
498 // Note : currently only one derived supported!!!!
499 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.PROPERTIES);
500 if (dataFromDerived.isRight()) {
501 return dataFromDerived.right().value();
503 Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
505 Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
507 if (properties != null) {
508 properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
509 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
513 Either<Map<String, PropertyDataDefinition>, String> eitherMerged = ToscaDataDefinition.mergeDataMaps(propertiesAll, properties);
514 if (eitherMerged.isRight()) {
515 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
516 log.debug("property {} cannot be overriden", eitherMerged.right().value());
517 return StorageOperationStatus.INVALID_PROPERTY;
520 if (!propertiesAll.isEmpty()) {
521 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
522 if (assosiateElementToData.isRight()) {
523 return assosiateElementToData.right().value();
526 return StorageOperationStatus.OK;
529 private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
530 Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
531 if (additionalInformation != null) {
532 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
533 if (assosiateElementToData.isRight()) {
534 return assosiateElementToData.right().value();
537 return StorageOperationStatus.OK;
540 protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, EdgeLabelEnum edge) {
541 Map<String, T> propertiesAll = new HashMap<>();
543 if (derivedResources != null && !derivedResources.isEmpty()) {
544 for (GraphVertex derived : derivedResources) {
545 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
546 if (derivedProperties.isRight()) {
547 if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
548 log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
549 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
554 List<GraphVertex> propList = derivedProperties.left().value();
555 for (GraphVertex propV : propList) {
556 Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
557 if (propertiesFromDerived != null) {
558 propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
559 propertiesAll.putAll(propertiesFromDerived);
564 return Either.left(propertiesAll);
567 protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
568 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
569 if (result.isLeft()) {
570 toscaElement.setArtifacts(result.left().value());
572 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
573 return result.right().value();
576 result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
577 if (result.isLeft()) {
578 toscaElement.setDeploymentArtifacts(result.left().value());
580 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
581 return result.right().value();
584 result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
585 if (result.isLeft()) {
586 toscaElement.setToscaArtifacts(result.left().value());
588 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
589 return result.right().value();
592 return TitanOperationStatus.OK;
595 protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
596 Map<String, String> allVersion = new HashMap<>();
598 allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
599 ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
600 Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
601 while (childResourceRes.isLeft()) {
602 GraphVertex child = childResourceRes.left().value();
603 allChildrenAndParants.add(child);
604 childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
606 TitanOperationStatus operationStatus = childResourceRes.right().value();
608 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
609 return operationStatus;
611 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
612 while (parentResourceRes.isLeft()) {
613 GraphVertex parent = parentResourceRes.left().value();
614 allChildrenAndParants.add(parent);
615 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
617 operationStatus = parentResourceRes.right().value();
618 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
619 return operationStatus;
621 allChildrenAndParants.stream().filter(vertex -> {
622 Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
623 return (isDeleted == null || isDeleted == false);
624 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
626 toscaElement.setAllVersions(allVersion);
627 return TitanOperationStatus.OK;
632 protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
634 Either<List<T>, StorageOperationStatus> result = null;
636 Map<GraphPropertyEnum, Object> props = null;
638 if (userId != null) {
639 props = new HashMap<>();
640 // for Designer retrieve specific user
641 props.put(GraphPropertyEnum.USERID, userId);
643 // in case of user id == null -> get all users by label
644 // for Tester and Admin retrieve all users
645 Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
646 if (usersByCriteria.isRight()) {
647 log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
648 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
650 List<GraphVertex> users = usersByCriteria.left().value();
652 List<T> components = new ArrayList<>();
653 List<T> componentsPerUser;
654 for (GraphVertex userV : users) {
656 HashSet<String> ids = new HashSet<String>();
657 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
658 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
659 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
660 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
663 // get all resource with current state
664 if (childrenVertecies.isLeft()) {
665 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
667 if (componentsPerUser != null) {
668 for (T comp : componentsPerUser) {
669 ids.add(comp.getUniqueId());
670 components.add(comp);
674 if (lastStateStates != null && !lastStateStates.isEmpty()) {
675 // get all resource with last state
676 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_STATE, JsonParseFlagEnum.NoParse);
677 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
678 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.LAST_STATE, childrenVertecies.right().value());
679 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
681 if (childrenVertecies.isLeft()) {
683 componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
684 if (componentsPerUser != null) {
685 for (T comp : componentsPerUser) {
688 if (ids.contains(comp.getUniqueId())) {
691 if (isFirst == true) {
692 components.add(comp);
702 result = Either.left(components);
707 private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
708 List<T> components = new ArrayList<>();
709 for (GraphVertex node : vertices) {
711 Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
712 while (edges.hasNext()) {
713 Edge edge = edges.next();
714 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
716 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
717 if (nodeState == null) {
718 log.debug("no supported STATE {} for element {}", stateStr, node.getUniqueId());
721 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
723 Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
724 if (isDeleted != null && isDeleted) {
725 log.trace("Deleted element {}, discard", node.getUniqueId());
729 Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
732 ComponentTypeEnum componentType = node.getType();
733 // get only latest versions
735 if (componentType == null) {
736 log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
739 if (neededType == componentType) {
740 switch (componentType) {
743 handleNode(components, node, componentType);
746 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
747 if (isAbtract == null || false == isAbtract) {
748 handleNode(components, node, componentType);
752 log.debug("not supported node type {}", componentType);
763 protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
765 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
766 if (component.isRight()) {
767 log.debug("Failed to get component for id = {} error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
769 components.add(component.left().value());
773 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
774 Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
775 if (getVertexRes.isRight()) {
776 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
778 return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
781 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
783 log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
785 titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
787 T toscaElement = convertToComponent(vertexComponent);
789 TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
790 if (status != TitanOperationStatus.OK) {
791 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
794 status = setLastModifierFromGraph(vertexComponent, toscaElement);
795 if (status != TitanOperationStatus.OK) {
796 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
798 status = setCategoriesFromGraph(vertexComponent, toscaElement);
799 if (status != TitanOperationStatus.OK) {
800 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
802 if (!parametersFilter.isIgnoreAllVersions()) {
803 status = setAllVersions(vertexComponent, toscaElement);
804 if (status != TitanOperationStatus.OK) {
805 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
808 if (!parametersFilter.isIgnoreCapabilities()) {
809 status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
810 if (status != TitanOperationStatus.OK) {
811 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
814 if (!parametersFilter.isIgnoreRequirements()) {
815 status = setRequirementsFromGraph(vertexComponent, toscaElement);
816 if (status != TitanOperationStatus.OK) {
817 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
820 log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
821 return Either.left(toscaElement);
824 @SuppressWarnings("unchecked")
825 protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
826 ToscaElement toscaElement = null;
827 VertexTypeEnum label = componentV.getLabel();
830 toscaElement = new NodeType();
832 case TOPOLOGY_TEMPLATE:
833 toscaElement = new TopologyTemplate();
836 log.debug("Not supported tosca type {}", label);
840 Map<String, Object> jsonMetada = componentV.getMetadataJson();
841 if (toscaElement != null) {
842 toscaElement.setMetadata(jsonMetada);
844 return (T) toscaElement;
847 protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
848 List<CategoryDefinition> categories = new ArrayList<>();
849 SubCategoryDefinition subcategory;
851 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
852 if (childVertex.isRight()) {
853 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
854 return childVertex.right().value();
856 GraphVertex subCategoryV = childVertex.left().value();
857 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
858 subcategory = new SubCategoryDefinition();
859 subcategory.setUniqueId(subCategoryV.getUniqueId());
860 subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
861 subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
863 Type listTypeSubcat = new TypeToken<List<String>>() {
865 List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
866 subcategory.setIcons(iconsfromJsonSubcat);
868 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
869 if (parentVertex.isRight()) {
870 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
871 return childVertex.right().value();
873 GraphVertex categoryV = parentVertex.left().value();
874 metadataProperties = categoryV.getMetadataProperties();
876 CategoryDefinition category = new CategoryDefinition();
877 category.setUniqueId(categoryV.getUniqueId());
878 category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
879 category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
881 Type listTypeCat = new TypeToken<List<String>>() {
883 List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
884 category.setIcons(iconsfromJsonCat);
886 category.addSubCategory(subcategory);
887 categories.add(category);
888 toscaElement.setCategories(categories);
890 return TitanOperationStatus.OK;
893 public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
894 Either<T, StorageOperationStatus> result = null;
896 log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
897 if (toscaElementToUpdate == null) {
898 log.error("Service object is null");
899 result = Either.right(StorageOperationStatus.BAD_REQUEST);
903 String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
904 if (modifierUserId == null || modifierUserId.isEmpty()) {
905 log.error("UserId is missing in the request.");
906 result = Either.right(StorageOperationStatus.BAD_REQUEST);
909 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
911 if (findUser.isRight()) {
912 TitanOperationStatus status = findUser.right().value();
913 log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
917 GraphVertex modifierV = findUser.left().value();
918 // UserData modifierUserData = findUser.left().value();
919 String toscaElementId = toscaElementToUpdate.getUniqueId();
921 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
922 if (parentVertex.isRight()) {
923 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
924 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
926 GraphVertex userV = parentVertex.left().value();
927 String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
929 String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
931 if (currentModifier.equals(modifierUserId)) {
932 log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
934 log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
935 StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
936 log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
937 if (status != StorageOperationStatus.OK) {
938 result = Either.right(status);
943 final long currentTimeMillis = System.currentTimeMillis();
944 log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
945 elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
947 StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
948 if (checkCategories != StorageOperationStatus.OK) {
949 result = Either.right(checkCategories);
953 // update all data on vertex
954 fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
956 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
958 if (updateElement.isRight()) {
959 log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
960 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
963 GraphVertex updateElementV = updateElement.left().value();
965 // DE230195 in case resource name changed update TOSCA artifacts
966 // file names accordingly
967 String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
968 if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
969 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
970 if (resultToscaArt.isRight()) {
971 log.debug("Failed to get tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
972 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
975 Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
976 if (toscaArtifacts != null) {
977 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
978 generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
980 // TODO call to new Artifact operation in order to update list of artifacts
983 // US833308 VLI in service - specific network_role property value logic
984 if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
985 // update method logs success/error and returns boolean (true if nothing fails)
987 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
991 if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
992 StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
993 if (resultDerived != StorageOperationStatus.OK) {
994 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
995 return Either.right(resultDerived);
999 Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
1000 if (updatedResource.isRight()) {
1001 log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
1002 result = Either.right(StorageOperationStatus.BAD_REQUEST);
1006 T updatedResourceValue = updatedResource.left().value();
1007 result = Either.left(updatedResourceValue);
1012 protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
1013 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
1016 protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
1017 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
1020 private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
1021 Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
1022 .findAny().get().getValue();
1023 artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
1026 protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1027 StorageOperationStatus status = StorageOperationStatus.OK;
1028 List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1029 CategoryDefinition newCategory = newCategoryList.get(0);
1031 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1032 if (childVertex.isRight()) {
1033 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1034 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1036 GraphVertex subCategoryV = childVertex.left().value();
1037 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1038 String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1040 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1041 if (parentVertex.isRight()) {
1042 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1043 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1045 GraphVertex categoryV = parentVertex.left().value();
1046 metadataProperties = categoryV.getMetadataProperties();
1047 String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1049 boolean categoryWasChanged = false;
1051 String newCategoryName = newCategory.getName();
1052 SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1053 String newSubCategoryName = newSubcategory.getName();
1054 if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1055 // the category was changed
1056 categoryWasChanged = true;
1058 // the sub-category was changed
1059 if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1060 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1061 categoryWasChanged = true;
1064 if (categoryWasChanged) {
1065 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1067 if (getCategoryVertex.isRight()) {
1068 return getCategoryVertex.right().value();
1070 GraphVertex newCategoryV = getCategoryVertex.left().value();
1071 status = moveCategoryEdge(elementV, newCategoryV);
1072 log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1077 public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement, boolean isHighestVersions) {
1078 Either<List<GraphVertex>, TitanOperationStatus> listOfComponents;
1079 if (isHighestVersions) {
1080 listOfComponents = getListOfHighestComponents(componentType, toscaElement);
1082 listOfComponents = getListOfHighestAndAllCertifiedComponents(componentType, toscaElement);
1084 if (listOfComponents.isRight() && listOfComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1085 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfComponents.right().value()));
1087 List<T> result = new ArrayList<>();
1088 if (listOfComponents.isLeft()) {
1089 List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
1090 if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1091 for (GraphVertex vertexComponent : highestAndAllCertified) {
1092 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1093 if (component.isRight()) {
1094 log.debug("Failed to fetch ligth element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1095 return Either.right(component.right().value());
1097 result.add(component.left().value());
1102 return Either.left(result);
1105 private Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement) {
1106 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
1107 propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1108 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1110 if (componentType == ComponentTypeEnum.RESOURCE) {
1111 propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, false);
1114 Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
1115 propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
1117 return titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatch, propertiesHasNotToMatch, JsonParseFlagEnum.ParseMetadata);
1120 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, ToscaElementTypeEnum toscaElement) {
1121 long startFetchAllStates = System.currentTimeMillis();
1122 Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1123 propertiesToMatchCertified.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1124 propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1125 if (componentType == ComponentTypeEnum.RESOURCE) {
1126 propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1129 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1130 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1132 Either<List<GraphVertex>, TitanOperationStatus> certifiedNodes = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatchCertified, propertiesHasNotToMatchCertified,
1133 JsonParseFlagEnum.ParseMetadata);
1134 if (certifiedNodes.isRight() && certifiedNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1135 return Either.right(certifiedNodes.right().value());
1138 Map<GraphPropertyEnum, Object> propertiesToMatchHighest = new HashMap<>();
1139 propertiesToMatchHighest.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1140 propertiesToMatchHighest.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1141 if (componentType == ComponentTypeEnum.RESOURCE) {
1142 propertiesToMatchHighest.put(GraphPropertyEnum.IS_ABSTRACT, false);
1145 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchHighest = new HashMap<>();
1146 propertiesHasNotToMatchHighest.put(GraphPropertyEnum.IS_DELETED, true);
1147 propertiesHasNotToMatchHighest.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1149 Either<List<GraphVertex>, TitanOperationStatus> highestNode = titanDao.getByCriteria(ToscaElementTypeEnum.getVertexTypeByToscaType(toscaElement), propertiesToMatchHighest, propertiesHasNotToMatchHighest, JsonParseFlagEnum.ParseMetadata);
1150 if (highestNode.isRight() && highestNode.right().value() != TitanOperationStatus.NOT_FOUND) {
1151 return Either.right(highestNode.right().value());
1154 long endFetchAllStates = System.currentTimeMillis();
1156 List<GraphVertex> allNodes = new ArrayList<>();
1158 if (certifiedNodes.isLeft()) {
1159 allNodes.addAll(certifiedNodes.left().value());
1161 if (highestNode.isLeft()) {
1162 allNodes.addAll(highestNode.left().value());
1166 int nonCertifiedSize;
1168 if (certifiedNodes.isRight()) {
1171 certifiedSize = certifiedNodes.left().value().size();
1174 if (highestNode.isRight()) {
1175 nonCertifiedSize = 0;
1177 nonCertifiedSize = highestNode.left().value().size();
1180 log.debug("Fetch catalog {}s all states: certified {}, noncertified {}", componentType, certifiedSize, nonCertifiedSize);
1181 log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1182 return Either.left(allNodes);
1185 protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1187 // get all components marked for delete
1188 Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1189 props.put(GraphPropertyEnum.IS_DELETED, true);
1190 props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1192 Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1194 if (componentsToDelete.isRight()) {
1195 TitanOperationStatus error = componentsToDelete.right().value();
1196 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1197 log.trace("no components to delete");
1198 return Either.left(new ArrayList<>());
1200 log.info("failed to find components to delete. error : {}", error.name());
1201 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1204 return Either.left(componentsToDelete.left().value());
1207 protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1208 Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1209 if (result.isLeft()) {
1210 toscaElement.setAdditionalInformation(result.left().value());
1212 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1213 return result.right().value();
1216 return TitanOperationStatus.OK;
1219 // --------------------------------------------
1220 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1222 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1224 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1226 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1228 protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1230 protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1232 protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1234 protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1236 protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1238 public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);