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 com.google.gson.Gson;
24 import com.google.gson.reflect.TypeToken;
25 import fj.data.Either;
26 import org.apache.tinkerpop.gremlin.structure.Direction;
27 import org.apache.tinkerpop.gremlin.structure.Edge;
28 import org.apache.tinkerpop.gremlin.structure.Vertex;
29 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
30 import org.openecomp.sdc.be.config.ConfigurationManager;
31 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
32 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
33 import org.openecomp.sdc.be.dao.jsongraph.types.EdgePropertyEnum;
34 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
35 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
36 import org.openecomp.sdc.be.dao.jsongraph.utils.JsonParserUtils;
37 import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary;
38 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
39 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
40 import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition;
41 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
42 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
43 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
44 import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields;
45 import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum;
46 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
47 import org.openecomp.sdc.be.model.ComponentParametersView;
48 import org.openecomp.sdc.be.model.LifecycleStateEnum;
49 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
50 import org.openecomp.sdc.be.model.category.CategoryDefinition;
51 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
52 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
53 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
54 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
55 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
56 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
57 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
58 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
59 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
60 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
61 import org.openecomp.sdc.common.util.ValidationUtils;
62 import org.slf4j.Logger;
63 import org.slf4j.LoggerFactory;
64 import org.springframework.beans.factory.annotation.Autowired;
65 import org.springframework.util.StopWatch;
67 import java.lang.reflect.Type;
68 import java.util.ArrayList;
69 import java.util.HashMap;
70 import java.util.HashSet;
71 import java.util.Iterator;
72 import java.util.List;
74 import java.util.Map.Entry;
77 public abstract class ToscaElementOperation extends BaseOperation {
78 private static Logger log = LoggerFactory.getLogger(ToscaElementOperation.class.getName());
80 private static final Gson gson = new Gson();
82 protected Gson getGson() {
87 protected CategoryOperation categoryOperation;
89 protected Either<GraphVertex, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, ToscaElementTypeEnum nodeType, JsonParseFlagEnum parseFlag) {
91 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
92 propertiesToMatch.put(GraphPropertyEnum.UNIQUE_ID, uniqueId);
94 VertexTypeEnum vertexType = ToscaElementTypeEnum.getVertexTypeByToscaType(nodeType);
95 Either<List<GraphVertex>, TitanOperationStatus> getResponse = titanDao.getByCriteria(vertexType, propertiesToMatch, parseFlag);
96 if (getResponse.isRight()) {
97 log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", vertexType, uniqueId, getResponse.right().value());
98 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value()));
101 List<GraphVertex> componentList = getResponse.left().value();
102 if (componentList.isEmpty()) {
103 log.debug("Component with type {} and unique id {} was not found", vertexType, uniqueId);
104 return Either.right(StorageOperationStatus.NOT_FOUND);
106 GraphVertex vertexG = componentList.get(0);
107 return Either.left(vertexG);
110 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId) {
111 return getToscaElement(uniqueId, new ComponentParametersView());
114 public Either<GraphVertex, StorageOperationStatus> markComponentToDelete(GraphVertex componentToDelete) {
115 Either<GraphVertex, StorageOperationStatus> result = null;
117 Boolean isDeleted = (Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
118 if (isDeleted != null && isDeleted && !(Boolean) componentToDelete.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION)) {
119 // component already marked for delete
120 result = Either.left(componentToDelete);
124 componentToDelete.addMetadataProperty(GraphPropertyEnum.IS_DELETED, Boolean.TRUE);
125 componentToDelete.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, System.currentTimeMillis());
127 Either<GraphVertex, TitanOperationStatus> updateNode = titanDao.updateVertex(componentToDelete);
129 StorageOperationStatus updateComponent;
130 if (updateNode.isRight()) {
131 log.debug("Failed to update component {}. status is {}", componentToDelete.getUniqueId(), updateNode.right().value());
132 updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value());
133 result = Either.right(updateComponent);
137 result = Either.left(componentToDelete);
143 * Performs a shadow clone of previousToscaElement
145 * @param previousToscaElement
146 * @param nextToscaElement
150 public Either<GraphVertex, StorageOperationStatus> cloneToscaElement(GraphVertex previousToscaElement, GraphVertex nextToscaElement, GraphVertex user) {
152 Either<GraphVertex, StorageOperationStatus> result = null;
153 GraphVertex createdToscaElementVertex = null;
154 TitanOperationStatus status;
156 Either<GraphVertex, TitanOperationStatus> createNextVersionRes = titanDao.createVertex(nextToscaElement);
157 if (createNextVersionRes.isRight()) {
158 status = createNextVersionRes.right().value();
159 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create tosca element vertex {} with version {} on graph. Status is {}. ", previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME),
160 previousToscaElement.getMetadataProperty(GraphPropertyEnum.VERSION), status);
161 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
163 if (result == null) {
164 createdToscaElementVertex = createNextVersionRes.left().value();
165 Map<EdgePropertyEnum, Object> properties = new HashMap<EdgePropertyEnum, Object>();
166 properties.put(EdgePropertyEnum.STATE, createdToscaElementVertex.getMetadataProperty(GraphPropertyEnum.STATE));
167 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.STATE, properties);
168 if (status != TitanOperationStatus.OK) {
169 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(),
170 previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
171 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
174 if (result == null) {
175 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.LAST_MODIFIER, new HashMap<>());
176 if (status != TitanOperationStatus.OK) {
177 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(),
178 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
179 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
182 if (result == null) {
183 status = titanDao.createEdge(user.getVertex(), createdToscaElementVertex.getVertex(), EdgeLabelEnum.CREATOR, new HashMap<>());
184 if (status != TitanOperationStatus.OK) {
185 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(),
186 nextToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME), status);
187 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
190 if (result == null) {
191 Iterator<Edge> edgesToCopyIter = previousToscaElement.getVertex().edges(Direction.OUT);
192 while (edgesToCopyIter.hasNext()) {
193 Edge currEdge = edgesToCopyIter.next();
194 Vertex currVertex = currEdge.inVertex();
195 status = titanDao.createEdge(createdToscaElementVertex.getVertex(), currVertex, EdgeLabelEnum.getEdgeLabelEnum(currEdge.label()), currEdge);
196 if (status != TitanOperationStatus.OK) {
197 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to create edge with label {} from tosca element vertex {} to vertex with label {} on graph. Status is {}. ", currEdge.label(), createdToscaElementVertex.getUniqueId(),
198 currVertex.property(GraphPropertyEnum.LABEL.getProperty()), status);
199 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
205 if (result == null) {
206 result = Either.left(createdToscaElementVertex);
208 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to clone tosca element {} with the name {}. ", previousToscaElement.getUniqueId(), previousToscaElement.getMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME));
213 protected TitanOperationStatus setLastModifierFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
214 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
215 if (parentVertex.isRight()) {
216 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
217 return parentVertex.right().value();
219 GraphVertex userV = parentVertex.left().value();
220 String userId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
221 toscaElement.setLastUpdaterUserId(userId);
222 toscaElement.setLastUpdaterFullName(buildFullName(userV));
223 return TitanOperationStatus.OK;
226 public String buildFullName(GraphVertex userV) {
228 String fullName = (String) userV.getMetadataProperty(GraphPropertyEnum.FIRST_NAME);
229 if (fullName == null) {
232 fullName = fullName + " ";
234 String lastName = (String) userV.getMetadataProperty(GraphPropertyEnum.LAST_NAME);
235 if (lastName != null) {
236 fullName += lastName;
241 protected TitanOperationStatus setCreatorFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
242 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(componentV, EdgeLabelEnum.CREATOR, JsonParseFlagEnum.NoParse);
243 if (parentVertex.isRight()) {
244 log.debug("Failed to fetch creator for tosca element with id {} error {}", componentV.getUniqueId(), parentVertex.right().value());
245 return parentVertex.right().value();
247 GraphVertex userV = parentVertex.left().value();
248 String creatorUserId = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
249 toscaElement.setCreatorUserId(creatorUserId);
250 toscaElement.setCreatorFullName(buildFullName(userV));
252 return TitanOperationStatus.OK;
255 protected <T extends ToscaElement> T getResourceMetaDataFromResource(T toscaElement) {
256 if (toscaElement.getNormalizedName() == null || toscaElement.getNormalizedName().isEmpty()) {
257 toscaElement.setNormalizedName(ValidationUtils.normaliseComponentName(toscaElement.getName()));
259 if (toscaElement.getSystemName() == null || toscaElement.getSystemName().isEmpty()) {
260 toscaElement.setSystemName(ValidationUtils.convertToSystemName(toscaElement.getName()));
263 LifecycleStateEnum lifecycleStateEnum = toscaElement.getLifecycleState();
264 if (lifecycleStateEnum == null) {
265 toscaElement.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT);
267 long currentDate = System.currentTimeMillis();
268 if (toscaElement.getCreationDate() == null) {
269 toscaElement.setCreationDate(currentDate);
271 toscaElement.setLastUpdateDate(currentDate);
276 protected void fillCommonMetadata(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
277 if (toscaElement.isHighestVersion() == null) {
278 toscaElement.setHighestVersion(true);
280 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_DELETED, toscaElement.getMetadataValue(JsonPresentationFields.IS_DELETED));
281 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, toscaElement.getMetadataValueOrDefault(JsonPresentationFields.HIGHEST_VERSION, Boolean.TRUE));
282 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.STATE, toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
283 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.RESOURCE_TYPE, toscaElement.getMetadataValue(JsonPresentationFields.RESOURCE_TYPE));
284 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.VERSION, toscaElement.getMetadataValue(JsonPresentationFields.VERSION));
285 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NORMALIZED_NAME, toscaElement.getMetadataValue(JsonPresentationFields.NORMALIZED_NAME));
286 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UNIQUE_ID, toscaElement.getMetadataValue(JsonPresentationFields.UNIQUE_ID));
287 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME, toscaElement.getMetadataValue(JsonPresentationFields.TOSCA_RESOURCE_NAME));
288 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.UUID, toscaElement.getMetadataValue(JsonPresentationFields.UUID));
289 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.IS_ABSTRACT, toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT));
290 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.INVARIANT_UUID, toscaElement.getMetadataValue(JsonPresentationFields.INVARIANT_UUID));
291 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.NAME, toscaElement.getMetadataValue(JsonPresentationFields.NAME));
292 nodeTypeVertex.addMetadataProperty(GraphPropertyEnum.SYSTEM_NAME, toscaElement.getMetadataValue(JsonPresentationFields.SYSTEM_NAME));
293 toscaElement.getMetadata().entrySet().stream().filter(e -> e.getValue() != null).forEach(e -> nodeTypeVertex.setJsonMetadataField(JsonPresentationFields.getByPresentation(e.getKey()), e.getValue()));
295 nodeTypeVertex.setUniqueId(toscaElement.getUniqueId());
296 nodeTypeVertex.setType(toscaElement.getComponentType());
300 protected StorageOperationStatus assosiateToUsers(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
302 String userId = toscaElement.getCreatorUserId();
304 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(userId);
306 if (findUser.isRight()) {
307 TitanOperationStatus status = findUser.right().value();
308 log.error("Cannot find user {} in the graph. status is {}", userId, status);
309 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
312 GraphVertex creatorVertex = findUser.left().value();
313 GraphVertex updaterVertex = creatorVertex;
314 String updaterId = toscaElement.getLastUpdaterUserId();
315 if (updaterId != null && !updaterId.equals(userId)) {
316 findUser = findUserVertex(updaterId);
317 if (findUser.isRight()) {
318 TitanOperationStatus status = findUser.right().value();
319 log.error("Cannot find user {} in the graph. status is {}", userId, status);
320 return DaoStatusConverter.convertTitanStatusToStorageStatus(status);
322 updaterVertex = findUser.left().value();
325 Map<EdgePropertyEnum, Object> props = new HashMap<EdgePropertyEnum, Object>();
326 props.put(EdgePropertyEnum.STATE, (String) toscaElement.getMetadataValue(JsonPresentationFields.LIFECYCLE_STATE));
328 TitanOperationStatus result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.STATE, props);
329 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.STATE);
330 if (TitanOperationStatus.OK != result) {
331 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
333 result = titanDao.createEdge(updaterVertex, nodeTypeVertex, EdgeLabelEnum.LAST_MODIFIER, null);
334 log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
335 if (!result.equals(TitanOperationStatus.OK)) {
336 log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.LAST_MODIFIER);
337 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
340 toscaElement.setLastUpdaterUserId(toscaElement.getCreatorUserId());
341 toscaElement.setLastUpdaterFullName(toscaElement.getCreatorFullName());
343 result = titanDao.createEdge(creatorVertex, nodeTypeVertex, EdgeLabelEnum.CREATOR, null);
344 log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
345 if (!result.equals(TitanOperationStatus.OK)) {
346 log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, nodeTypeVertex.getUniqueId(), EdgeLabelEnum.CREATOR);
347 return DaoStatusConverter.convertTitanStatusToStorageStatus(result);
349 return StorageOperationStatus.OK;
352 protected StorageOperationStatus assosiateResourceMetadataToCategory(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
353 String subcategoryName = nodeType.getCategories().get(0).getSubcategories().get(0).getName();
354 String categoryName = nodeType.getCategories().get(0).getName();
355 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(nodeType.getUniqueId(), subcategoryName, categoryName);
357 if (getCategoryVertex.isRight()) {
358 return getCategoryVertex.right().value();
361 GraphVertex subCategoryV = getCategoryVertex.left().value();
363 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, subCategoryV, EdgeLabelEnum.CATEGORY, new HashMap<>());
364 if (createEdge != TitanOperationStatus.OK) {
365 log.trace("Failed to associate resource {} to category {} with id {}", nodeType.getUniqueId(), subcategoryName, subCategoryV.getUniqueId());
366 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
368 return StorageOperationStatus.OK;
371 protected Either<GraphVertex, StorageOperationStatus> getResourceCategoryVertex(String elementId, String subcategoryName, String categoryName) {
372 Either<GraphVertex, StorageOperationStatus> category = categoryOperation.getCategory(categoryName, VertexTypeEnum.RESOURCE_CATEGORY);
373 if (category.isRight()) {
374 log.trace("Failed to fetch category {} for resource {} error {}", categoryName, elementId, category.right().value());
375 return Either.right(category.right().value());
377 GraphVertex categoryV = category.left().value();
379 if (subcategoryName != null) {
380 Either<GraphVertex, StorageOperationStatus> subCategory = categoryOperation.getSubCategoryForCategory(categoryV, subcategoryName);
381 if (subCategory.isRight()) {
382 log.trace("Failed to fetch subcategory {} of category for resource {} error {}", subcategoryName, categoryName, elementId, subCategory.right().value());
383 return Either.right(subCategory.right().value());
386 GraphVertex subCategoryV = subCategory.left().value();
387 return Either.left(subCategoryV);
389 return Either.left(categoryV);
392 private StorageOperationStatus associateArtifactsToResource(GraphVertex nodeTypeVertex, ToscaElement toscaElement) {
393 Map<String, ArtifactDataDefinition> artifacts = toscaElement.getArtifacts();
394 Either<GraphVertex, StorageOperationStatus> status;
395 if (artifacts != null) {
396 artifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
397 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
398 a.setUniqueId(uniqueId);
400 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ARTIFACTS, EdgeLabelEnum.ARTIFACTS, artifacts);
401 if (status.isRight()) {
402 return status.right().value();
405 Map<String, ArtifactDataDefinition> toscaArtifacts = toscaElement.getToscaArtifacts();
406 if (toscaArtifacts != null) {
407 toscaArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
408 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
409 a.setUniqueId(uniqueId);
411 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.TOSCA_ARTIFACTS, EdgeLabelEnum.TOSCA_ARTIFACTS, toscaArtifacts);
412 if (status.isRight()) {
413 return status.right().value();
416 Map<String, ArtifactDataDefinition> deploymentArtifacts = toscaElement.getDeploymentArtifacts();
417 if (deploymentArtifacts != null) {
418 deploymentArtifacts.values().stream().filter(a -> a.getUniqueId() == null).forEach(a -> {
419 String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId().toLowerCase(), a.getArtifactLabel().toLowerCase());
420 a.setUniqueId(uniqueId);
422 status = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.DEPLOYMENT_ARTIFACTS, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS, deploymentArtifacts);
423 if (status.isRight()) {
424 return status.right().value();
427 return StorageOperationStatus.OK;
430 protected TitanOperationStatus disassociateAndDeleteCommonElements(GraphVertex toscaElementVertex) {
431 TitanOperationStatus status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ARTIFACTS);
432 if (status != TitanOperationStatus.OK) {
433 log.debug("Failed to disaccociate artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
436 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.TOSCA_ARTIFACTS);
437 if (status != TitanOperationStatus.OK) {
438 log.debug("Failed to disaccociate tosca artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
441 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
442 if (status != TitanOperationStatus.OK) {
443 log.debug("Failed to deployment artifact for {} error {}", toscaElementVertex.getUniqueId(), status);
446 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.PROPERTIES);
447 if (status != TitanOperationStatus.OK) {
448 log.debug("Failed to disaccociate properties for {} error {}", toscaElementVertex.getUniqueId(), status);
451 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
452 if (status != TitanOperationStatus.OK) {
453 log.debug("Failed to disaccociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
456 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ADDITIONAL_INFORMATION);
457 if (status != TitanOperationStatus.OK) {
458 log.debug("Failed to disaccociate additional information for {} error {}", toscaElementVertex.getUniqueId(), status);
461 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
462 if (status != TitanOperationStatus.OK) {
463 log.debug("Failed to disaccociate capabilities for {} error {}", toscaElementVertex.getUniqueId(), status);
466 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
467 if (status != TitanOperationStatus.OK) {
468 log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
471 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.FORWARDING_PATH);
472 if (status != TitanOperationStatus.OK) {
473 log.debug("Failed to disaccociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
476 return TitanOperationStatus.OK;
479 protected StorageOperationStatus assosiateCommonForToscaElement(GraphVertex nodeTypeVertex, ToscaElement toscaElement, List<GraphVertex> derivedResources) {
481 StorageOperationStatus associateUsers = assosiateToUsers(nodeTypeVertex, toscaElement);
482 if (associateUsers != StorageOperationStatus.OK) {
483 return associateUsers;
485 StorageOperationStatus associateArtifacts = associateArtifactsToResource(nodeTypeVertex, toscaElement);
486 if (associateArtifacts != StorageOperationStatus.OK) {
487 return associateArtifacts;
489 StorageOperationStatus associateProperties = associatePropertiesToResource(nodeTypeVertex, toscaElement, derivedResources);
490 if (associateProperties != StorageOperationStatus.OK) {
491 return associateProperties;
493 StorageOperationStatus associateAdditionaInfo = associateAdditionalInfoToResource(nodeTypeVertex, toscaElement);
494 if (associateAdditionaInfo != StorageOperationStatus.OK) {
495 return associateAdditionaInfo;
497 if (needConnectToCatalog(toscaElement)) {
498 StorageOperationStatus associateToCatalog = associateToCatalogRoot(nodeTypeVertex);
499 if (associateToCatalog != StorageOperationStatus.OK) {
500 return associateToCatalog;
503 return StorageOperationStatus.OK;
506 private boolean needConnectToCatalog(ToscaElement toscaElement) {
507 Boolean isAbstract = (Boolean) toscaElement.getMetadataValue(JsonPresentationFields.IS_ABSTRACT);
508 if (isAbstract != null && isAbstract) {
511 return toscaElement.isHighestVersion();
514 private StorageOperationStatus associateToCatalogRoot(GraphVertex nodeTypeVertex) {
515 Either<GraphVertex, TitanOperationStatus> catalog = titanDao.getVertexByLabel(VertexTypeEnum.CATALOG_ROOT);
516 if (catalog.isRight()) {
517 log.debug("Failed to fetch catalog vertex. error {}", catalog.right().value());
518 return DaoStatusConverter.convertTitanStatusToStorageStatus(catalog.right().value());
520 TitanOperationStatus createEdge = titanDao.createEdge(catalog.left().value(), nodeTypeVertex, EdgeLabelEnum.CATALOG_ELEMENT, null);
522 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
525 protected StorageOperationStatus associatePropertiesToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType, List<GraphVertex> derivedResources) {
526 // Note : currently only one derived supported!!!!
527 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.PROPERTIES);
528 if (dataFromDerived.isRight()) {
529 return dataFromDerived.right().value();
531 Map<String, PropertyDataDefinition> propertiesAll = dataFromDerived.left().value();
533 Map<String, PropertyDataDefinition> properties = nodeType.getProperties();
535 if (properties != null) {
536 properties.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
537 String uid = UniqueIdBuilder.buildPropertyUniqueId(nodeTypeVertex.getUniqueId(), p.getName());
541 Either<Map<String, PropertyDataDefinition>, String> eitherMerged = ToscaDataDefinition.mergeDataMaps(propertiesAll, properties);
542 if (eitherMerged.isRight()) {
543 // TODO re-factor error handling - moving BL to operation resulted in loss of info about the invalid property
544 log.debug("property {} cannot be overriden", eitherMerged.right().value());
545 return StorageOperationStatus.INVALID_PROPERTY;
548 if (!propertiesAll.isEmpty()) {
549 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.PROPERTIES, EdgeLabelEnum.PROPERTIES, propertiesAll);
550 if (assosiateElementToData.isRight()) {
551 return assosiateElementToData.right().value();
554 return StorageOperationStatus.OK;
557 private StorageOperationStatus associateAdditionalInfoToResource(GraphVertex nodeTypeVertex, ToscaElement nodeType) {
558 Map<String, AdditionalInfoParameterDataDefinition> additionalInformation = nodeType.getAdditionalInformation();
559 if (additionalInformation != null) {
560 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, additionalInformation);
561 if (assosiateElementToData.isRight()) {
562 return assosiateElementToData.right().value();
565 return StorageOperationStatus.OK;
568 protected <T extends ToscaDataDefinition> Either<Map<String, T>, StorageOperationStatus> getDataFromDerived(List<GraphVertex> derivedResources, EdgeLabelEnum edge) {
569 Map<String, T> propertiesAll = new HashMap<>();
571 if (derivedResources != null && !derivedResources.isEmpty()) {
572 for (GraphVertex derived : derivedResources) {
573 Either<List<GraphVertex>, TitanOperationStatus> derivedProperties = titanDao.getChildrenVertecies(derived, edge, JsonParseFlagEnum.ParseJson);
574 if (derivedProperties.isRight()) {
575 if (derivedProperties.right().value() != TitanOperationStatus.NOT_FOUND) {
576 log.debug("Failed to get properties for derived from {} error {}", derived.getUniqueId(), derivedProperties.right().value());
577 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(derivedProperties.right().value()));
582 List<GraphVertex> propList = derivedProperties.left().value();
583 for (GraphVertex propV : propList) {
584 Map<String, T> propertiesFromDerived = (Map<String, T>) propV.getJson();
585 if (propertiesFromDerived != null) {
586 propertiesFromDerived.entrySet().forEach(x -> x.getValue().setOwnerIdIfEmpty(derived.getUniqueId()));
587 propertiesAll.putAll(propertiesFromDerived);
592 return Either.left(propertiesAll);
595 protected TitanOperationStatus setArtifactsFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
596 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ARTIFACTS);
597 if (result.isLeft()) {
598 toscaElement.setArtifacts(result.left().value());
600 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
601 return result.right().value();
604 result = getDataFromGraph(componentV, EdgeLabelEnum.DEPLOYMENT_ARTIFACTS);
605 if (result.isLeft()) {
606 toscaElement.setDeploymentArtifacts(result.left().value());
608 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
609 return result.right().value();
612 result = getDataFromGraph(componentV, EdgeLabelEnum.TOSCA_ARTIFACTS);
613 if (result.isLeft()) {
614 toscaElement.setToscaArtifacts(result.left().value());
616 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
617 return result.right().value();
620 return TitanOperationStatus.OK;
623 protected TitanOperationStatus setAllVersions(GraphVertex componentV, ToscaElement toscaElement) {
624 Map<String, String> allVersion = new HashMap<>();
626 allVersion.put((String) componentV.getMetadataProperty(GraphPropertyEnum.VERSION), componentV.getUniqueId());
627 ArrayList<GraphVertex> allChildrenAndParants = new ArrayList<GraphVertex>();
628 Either<GraphVertex, TitanOperationStatus> childResourceRes = titanDao.getChildVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
629 while (childResourceRes.isLeft()) {
630 GraphVertex child = childResourceRes.left().value();
631 allChildrenAndParants.add(child);
632 childResourceRes = titanDao.getChildVertex(child, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
634 TitanOperationStatus operationStatus = childResourceRes.right().value();
636 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
637 return operationStatus;
639 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getParentVertex(componentV, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
640 while (parentResourceRes.isLeft()) {
641 GraphVertex parent = parentResourceRes.left().value();
642 allChildrenAndParants.add(parent);
643 parentResourceRes = titanDao.getParentVertex(parent, EdgeLabelEnum.VERSION, JsonParseFlagEnum.NoParse);
645 operationStatus = parentResourceRes.right().value();
646 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
647 return operationStatus;
649 allChildrenAndParants.stream().filter(vertex -> {
650 Boolean isDeleted = (Boolean) vertex.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
651 return (isDeleted == null || isDeleted == false);
652 }).forEach(vertex -> allVersion.put((String) vertex.getMetadataProperty(GraphPropertyEnum.VERSION), vertex.getUniqueId()));
654 toscaElement.setAllVersions(allVersion);
655 return TitanOperationStatus.OK;
660 protected <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, ComponentTypeEnum neededType) {
662 Either<List<T>, StorageOperationStatus> result = null;
664 Map<GraphPropertyEnum, Object> props = null;
666 if (userId != null) {
667 props = new HashMap<>();
668 // for Designer retrieve specific user
669 props.put(GraphPropertyEnum.USERID, userId);
671 // in case of user id == null -> get all users by label
672 // for Tester and Admin retrieve all users
673 Either<List<GraphVertex>, TitanOperationStatus> usersByCriteria = titanDao.getByCriteria(VertexTypeEnum.USER, props, JsonParseFlagEnum.NoParse);
674 if (usersByCriteria.isRight()) {
675 log.debug("Failed to fetch users by criteria {} error {}", props, usersByCriteria.right().value());
676 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(usersByCriteria.right().value()));
678 List<GraphVertex> users = usersByCriteria.left().value();
680 List<T> components = new ArrayList<>();
681 List<T> componentsPerUser;
682 for (GraphVertex userV : users) {
684 HashSet<String> ids = new HashSet<String>();
685 Either<List<GraphVertex>, TitanOperationStatus> childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.STATE, JsonParseFlagEnum.NoParse);
686 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
687 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.STATE, childrenVertecies.right().value());
688 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
691 // get all resource with current state
692 if (childrenVertecies.isLeft()) {
693 componentsPerUser = fetchComponents(lifecycleStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.STATE);
695 if (componentsPerUser != null) {
696 for (T comp : componentsPerUser) {
697 ids.add(comp.getUniqueId());
698 components.add(comp);
702 if (lastStateStates != null && !lastStateStates.isEmpty()) {
703 // get all resource with last state
704 childrenVertecies = titanDao.getChildrenVertecies(userV, EdgeLabelEnum.LAST_STATE, JsonParseFlagEnum.NoParse);
705 if (childrenVertecies.isRight() && childrenVertecies.right().value() != TitanOperationStatus.NOT_FOUND) {
706 log.debug("Failed to fetch children vertices for user {} by edge {} error {}", userV.getMetadataProperty(GraphPropertyEnum.USERID), EdgeLabelEnum.LAST_STATE, childrenVertecies.right().value());
707 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenVertecies.right().value()));
709 if (childrenVertecies.isLeft()) {
711 componentsPerUser = fetchComponents(lastStateStates, childrenVertecies.left().value(), neededType, EdgeLabelEnum.LAST_STATE);
712 if (componentsPerUser != null) {
713 for (T comp : componentsPerUser) {
716 if (ids.contains(comp.getUniqueId())) {
719 if (isFirst == true) {
720 components.add(comp);
730 result = Either.left(components);
735 private <T extends ToscaElement> List<T> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, List<GraphVertex> vertices, ComponentTypeEnum neededType, EdgeLabelEnum edgelabel) {
736 List<T> components = new ArrayList<>();
737 for (GraphVertex node : vertices) {
739 Iterator<Edge> edges = node.getVertex().edges(Direction.IN, edgelabel.name());
740 while (edges.hasNext()) {
741 Edge edge = edges.next();
742 String stateStr = (String) titanDao.getProperty(edge, EdgePropertyEnum.STATE);
744 LifecycleStateEnum nodeState = LifecycleStateEnum.findState(stateStr);
745 if (nodeState == null) {
746 log.debug("no supported STATE {} for element {}", stateStr, node.getUniqueId());
749 if (lifecycleStates != null && lifecycleStates.contains(nodeState)) {
751 Boolean isDeleted = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_DELETED);
752 if (isDeleted != null && isDeleted) {
753 log.trace("Deleted element {}, discard", node.getUniqueId());
757 Boolean isHighest = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION);
760 ComponentTypeEnum componentType = node.getType();
761 // get only latest versions
763 if (componentType == null) {
764 log.debug("No supported type {} for vertex {}", componentType, node.getUniqueId());
767 if (neededType == componentType) {
768 switch (componentType) {
771 handleNode(components, node, componentType);
774 Boolean isAbtract = (Boolean) node.getMetadataProperty(GraphPropertyEnum.IS_ABSTRACT);
775 if (isAbtract == null || false == isAbtract) {
776 handleNode(components, node, componentType);
780 log.debug("not supported node type {}", componentType);
791 protected <T extends ToscaElement> void handleNode(List<T> components, GraphVertex vertexComponent, ComponentTypeEnum nodeType) {
793 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, nodeType, new ComponentParametersView(true));
794 if (component.isRight()) {
795 log.debug("Failed to get component for id = {} error : {} skip resource", vertexComponent.getUniqueId(), component.right().value());
797 components.add(component.left().value());
801 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(String componentUid, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
802 Either<GraphVertex, TitanOperationStatus> getVertexRes = titanDao.getVertexById(componentUid);
803 if (getVertexRes.isRight()) {
804 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getVertexRes.right().value()));
806 return getLightComponent(getVertexRes.left().value(), nodeType, parametersFilter);
809 protected <T extends ToscaElement> Either<T, StorageOperationStatus> getLightComponent(GraphVertex vertexComponent, ComponentTypeEnum nodeType, ComponentParametersView parametersFilter) {
811 log.trace("Starting to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
813 titanDao.parseVertexProperties(vertexComponent, JsonParseFlagEnum.ParseMetadata);
815 T toscaElement = convertToComponent(vertexComponent);
817 TitanOperationStatus status = setCreatorFromGraph(vertexComponent, toscaElement);
818 if (status != TitanOperationStatus.OK) {
819 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
822 status = setLastModifierFromGraph(vertexComponent, toscaElement);
823 if (status != TitanOperationStatus.OK) {
824 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
826 status = setCategoriesFromGraph(vertexComponent, toscaElement);
827 if (status != TitanOperationStatus.OK) {
828 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
830 if (!parametersFilter.isIgnoreAllVersions()) {
831 status = setAllVersions(vertexComponent, toscaElement);
832 if (status != TitanOperationStatus.OK) {
833 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
836 if (!parametersFilter.isIgnoreCapabilities()) {
837 status = setCapabilitiesFromGraph(vertexComponent, toscaElement);
838 if (status != TitanOperationStatus.OK) {
839 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
842 if (!parametersFilter.isIgnoreRequirements()) {
843 status = setRequirementsFromGraph(vertexComponent, toscaElement);
844 if (status != TitanOperationStatus.OK) {
845 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
848 log.debug("Ended to build light component of type {}, id {}", nodeType, vertexComponent.getUniqueId());
849 return Either.left(toscaElement);
852 @SuppressWarnings("unchecked")
853 protected <T extends ToscaElement> T convertToComponent(GraphVertex componentV) {
854 ToscaElement toscaElement = null;
855 VertexTypeEnum label = componentV.getLabel();
858 toscaElement = new NodeType();
860 case TOPOLOGY_TEMPLATE:
861 toscaElement = new TopologyTemplate();
864 log.debug("Not supported tosca type {}", label);
868 Map<String, Object> jsonMetada = componentV.getMetadataJson();
869 if (toscaElement != null) {
870 toscaElement.setMetadata(jsonMetada);
872 return (T) toscaElement;
875 protected TitanOperationStatus setServiceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
876 Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
877 if (childVertex.isRight()) {
878 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
879 return childVertex.right().value();
881 Vertex categoryV = childVertex.left().value();
882 catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
884 return TitanOperationStatus.OK;
887 protected TitanOperationStatus setResourceCategoryFromGraphV(Vertex vertex, CatalogComponent catalogComponent) {
889 Either<Vertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(vertex, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
890 if (childVertex.isRight()) {
891 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, catalogComponent.getUniqueId(), childVertex.right().value());
892 return childVertex.right().value();
894 Vertex subCategoryV = childVertex.left().value();
895 catalogComponent.setSubCategoryNormalizedName((String) subCategoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
896 Either<Vertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
897 Vertex categoryV = parentVertex.left().value();
898 catalogComponent.setCategoryNormalizedName((String) categoryV.property(JsonPresentationFields.NORMALIZED_NAME.getPresentation()).value());
900 return TitanOperationStatus.OK;
903 protected TitanOperationStatus setResourceCategoryFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
904 List<CategoryDefinition> categories = new ArrayList<>();
905 SubCategoryDefinition subcategory;
907 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(componentV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
908 if (childVertex.isRight()) {
909 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, componentV.getUniqueId(), childVertex.right().value());
910 return childVertex.right().value();
912 GraphVertex subCategoryV = childVertex.left().value();
913 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
914 subcategory = new SubCategoryDefinition();
915 subcategory.setUniqueId(subCategoryV.getUniqueId());
916 subcategory.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
917 subcategory.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
919 Type listTypeSubcat = new TypeToken<List<String>>() {
921 List<String> iconsfromJsonSubcat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeSubcat);
922 subcategory.setIcons(iconsfromJsonSubcat);
924 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
925 if (parentVertex.isRight()) {
926 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
927 return childVertex.right().value();
929 GraphVertex categoryV = parentVertex.left().value();
930 metadataProperties = categoryV.getMetadataProperties();
932 CategoryDefinition category = new CategoryDefinition();
933 category.setUniqueId(categoryV.getUniqueId());
934 category.setNormalizedName((String) metadataProperties.get(GraphPropertyEnum.NORMALIZED_NAME));
935 category.setName((String) metadataProperties.get(GraphPropertyEnum.NAME));
937 Type listTypeCat = new TypeToken<List<String>>() {
939 List<String> iconsfromJsonCat = getGson().fromJson((String) metadataProperties.get(GraphPropertyEnum.ICONS), listTypeCat);
940 category.setIcons(iconsfromJsonCat);
942 category.addSubCategory(subcategory);
943 categories.add(category);
944 toscaElement.setCategories(categories);
946 return TitanOperationStatus.OK;
949 public <T extends ToscaElement> Either<T, StorageOperationStatus> updateToscaElement(T toscaElementToUpdate, GraphVertex elementV, ComponentParametersView filterResult) {
950 Either<T, StorageOperationStatus> result = null;
952 log.debug("In updateToscaElement. received component uid = {}", (toscaElementToUpdate == null ? null : toscaElementToUpdate.getUniqueId()));
953 if (toscaElementToUpdate == null) {
954 log.error("Service object is null");
955 result = Either.right(StorageOperationStatus.BAD_REQUEST);
959 String modifierUserId = toscaElementToUpdate.getLastUpdaterUserId();
960 if (modifierUserId == null || modifierUserId.isEmpty()) {
961 log.error("UserId is missing in the request.");
962 result = Either.right(StorageOperationStatus.BAD_REQUEST);
965 Either<GraphVertex, TitanOperationStatus> findUser = findUserVertex(modifierUserId);
967 if (findUser.isRight()) {
968 TitanOperationStatus status = findUser.right().value();
969 log.error("Cannot find user {} in the graph. status is {}", modifierUserId, status);
973 GraphVertex modifierV = findUser.left().value();
974 // UserData modifierUserData = findUser.left().value();
975 String toscaElementId = toscaElementToUpdate.getUniqueId();
977 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(elementV, EdgeLabelEnum.LAST_MODIFIER, JsonParseFlagEnum.NoParse);
978 if (parentVertex.isRight()) {
979 log.debug("Failed to fetch last modifier for tosca element with id {} error {}", toscaElementId, parentVertex.right().value());
980 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentVertex.right().value()));
982 GraphVertex userV = parentVertex.left().value();
983 String currentModifier = (String) userV.getMetadataProperty(GraphPropertyEnum.USERID);
985 String prevSystemName = (String) elementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
987 if (currentModifier.equals(modifierUserId)) {
988 log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier.");
990 log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId);
991 StorageOperationStatus status = moveLastModifierEdge(elementV, modifierV);
992 log.debug("Finish to update the last modifier user of the resource from {} to {}. status is {}", currentModifier, modifierUserId, status);
993 if (status != StorageOperationStatus.OK) {
994 result = Either.right(status);
999 final long currentTimeMillis = System.currentTimeMillis();
1000 log.debug("Going to update the last Update Date of the resource from {} to {}", elementV.getJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE), currentTimeMillis);
1001 elementV.setJsonMetadataField(JsonPresentationFields.LAST_UPDATE_DATE, currentTimeMillis);
1003 StorageOperationStatus checkCategories = validateCategories(toscaElementToUpdate, elementV);
1004 if (checkCategories != StorageOperationStatus.OK) {
1005 result = Either.right(checkCategories);
1009 // update all data on vertex
1010 fillToscaElementVertexData(elementV, toscaElementToUpdate, JsonParseFlagEnum.ParseMetadata);
1012 Either<GraphVertex, TitanOperationStatus> updateElement = titanDao.updateVertex(elementV);
1014 if (updateElement.isRight()) {
1015 log.error("Failed to update resource {}. status is {}", toscaElementId, updateElement.right().value());
1016 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateElement.right().value()));
1019 GraphVertex updateElementV = updateElement.left().value();
1021 // DE230195 in case resource name changed update TOSCA artifacts
1022 // file names accordingly
1023 String newSystemName = (String) updateElementV.getMetadataProperty(GraphPropertyEnum.SYSTEM_NAME);
1024 if (newSystemName != null && !newSystemName.equals(prevSystemName)) {
1025 Either<Map<String, ArtifactDataDefinition>, TitanOperationStatus> resultToscaArt = getDataFromGraph(updateElementV, EdgeLabelEnum.TOSCA_ARTIFACTS);
1026 if (resultToscaArt.isRight()) {
1027 log.debug("Failed to get tosca artifact from graph for tosca element {} error {}", toscaElementId, resultToscaArt.right().value());
1028 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resultToscaArt.right().value()));
1031 Map<String, ArtifactDataDefinition> toscaArtifacts = resultToscaArt.left().value();
1032 if (toscaArtifacts != null) {
1033 for (Entry<String, ArtifactDataDefinition> artifact : toscaArtifacts.entrySet()) {
1034 generateNewToscaFileName(toscaElementToUpdate.getComponentType().getValue().toLowerCase(), newSystemName, artifact.getValue());
1036 // TODO call to new Artifact operation in order to update list of artifacts
1039 // US833308 VLI in service - specific network_role property value logic
1040 if (ComponentTypeEnum.SERVICE == toscaElementToUpdate.getComponentType()) {
1041 // update method logs success/error and returns boolean (true if nothing fails)
1043 // updateServiceNameInVLIsNetworkRolePropertyValues(component, prevSystemName, newSystemName);
1047 if (toscaElementToUpdate.getComponentType() == ComponentTypeEnum.RESOURCE) {
1048 StorageOperationStatus resultDerived = updateDerived(toscaElementToUpdate, updateElementV);
1049 if (resultDerived != StorageOperationStatus.OK) {
1050 log.debug("Failed to update from derived data for element {} error {}", toscaElementId, resultDerived);
1051 return Either.right(resultDerived);
1055 Either<T, StorageOperationStatus> updatedResource = getToscaElement(updateElementV, filterResult);
1056 if (updatedResource.isRight()) {
1057 log.error("Failed to fetch tosca element {} after update , error {}", toscaElementId, updatedResource.right().value());
1058 result = Either.right(StorageOperationStatus.BAD_REQUEST);
1062 T updatedResourceValue = updatedResource.left().value();
1063 result = Either.left(updatedResourceValue);
1068 protected StorageOperationStatus moveLastModifierEdge(GraphVertex elementV, GraphVertex modifierV) {
1069 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, modifierV, EdgeLabelEnum.LAST_MODIFIER, Direction.IN));
1072 protected StorageOperationStatus moveCategoryEdge(GraphVertex elementV, GraphVertex categoryV) {
1073 return DaoStatusConverter.convertTitanStatusToStorageStatus(titanDao.moveEdge(elementV, categoryV, EdgeLabelEnum.CATEGORY, Direction.OUT));
1076 private void generateNewToscaFileName(String componentType, String componentName, ArtifactDataDefinition artifactInfo) {
1077 Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel()))
1078 .findAny().get().getValue();
1079 artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName"));
1082 protected <T extends ToscaElement> StorageOperationStatus validateResourceCategory(T toscaElementToUpdate, GraphVertex elementV) {
1083 StorageOperationStatus status = StorageOperationStatus.OK;
1084 List<CategoryDefinition> newCategoryList = toscaElementToUpdate.getCategories();
1085 CategoryDefinition newCategory = newCategoryList.get(0);
1087 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(elementV, EdgeLabelEnum.CATEGORY, JsonParseFlagEnum.NoParse);
1088 if (childVertex.isRight()) {
1089 log.debug("failed to fetch {} for tosca element with id {}, error {}", EdgeLabelEnum.CATEGORY, elementV.getUniqueId(), childVertex.right().value());
1090 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1092 GraphVertex subCategoryV = childVertex.left().value();
1093 Map<GraphPropertyEnum, Object> metadataProperties = subCategoryV.getMetadataProperties();
1094 String subCategoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1096 Either<GraphVertex, TitanOperationStatus> parentVertex = titanDao.getParentVertex(subCategoryV, EdgeLabelEnum.SUB_CATEGORY, JsonParseFlagEnum.NoParse);
1097 if (parentVertex.isRight()) {
1098 log.debug("failed to fetch {} for category with id {}, error {}", EdgeLabelEnum.SUB_CATEGORY, subCategoryV.getUniqueId(), parentVertex.right().value());
1099 return DaoStatusConverter.convertTitanStatusToStorageStatus(childVertex.right().value());
1101 GraphVertex categoryV = parentVertex.left().value();
1102 metadataProperties = categoryV.getMetadataProperties();
1103 String categoryNameCurrent = (String) metadataProperties.get(GraphPropertyEnum.NAME);
1105 boolean categoryWasChanged = false;
1107 String newCategoryName = newCategory.getName();
1108 SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0);
1109 String newSubCategoryName = newSubcategory.getName();
1110 if (newCategoryName != null && false == newCategoryName.equals(categoryNameCurrent)) {
1111 // the category was changed
1112 categoryWasChanged = true;
1114 // the sub-category was changed
1115 if (newSubCategoryName != null && false == newSubCategoryName.equals(subCategoryNameCurrent)) {
1116 log.debug("Going to update the category of the resource from {} to {}", categoryNameCurrent, newCategory);
1117 categoryWasChanged = true;
1120 if (categoryWasChanged) {
1121 Either<GraphVertex, StorageOperationStatus> getCategoryVertex = getResourceCategoryVertex(elementV.getUniqueId(), newSubCategoryName, newCategoryName);
1123 if (getCategoryVertex.isRight()) {
1124 return getCategoryVertex.right().value();
1126 GraphVertex newCategoryV = getCategoryVertex.left().value();
1127 status = moveCategoryEdge(elementV, newCategoryV);
1128 log.debug("Going to update the category of the resource from {} to {}. status is {}", categoryNameCurrent, newCategory, status);
1133 public <T extends ToscaElement> Either<List<T>, StorageOperationStatus> getElementCatalogData(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, boolean isHighestVersions) {
1134 Either<List<GraphVertex>, TitanOperationStatus> listOfComponents;
1135 if (isHighestVersions) {
1136 listOfComponents = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.NoParse);
1138 listOfComponents = getListOfHighestAndAllCertifiedComponents(componentType, excludeTypes);
1141 if (listOfComponents.isRight() && listOfComponents.right().value() != TitanOperationStatus.NOT_FOUND) {
1142 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(listOfComponents.right().value()));
1144 List<T> result = new ArrayList<>();
1145 if (listOfComponents.isLeft()) {
1146 List<GraphVertex> highestAndAllCertified = listOfComponents.left().value();
1147 if (highestAndAllCertified != null && false == highestAndAllCertified.isEmpty()) {
1148 for (GraphVertex vertexComponent : highestAndAllCertified) {
1149 Either<T, StorageOperationStatus> component = getLightComponent(vertexComponent, componentType, new ComponentParametersView(true));
1150 if (component.isRight()) {
1151 log.debug("Failed to fetch light element for {} error {}", vertexComponent.getUniqueId(), component.right().value());
1152 return Either.right(component.right().value());
1154 result.add(component.left().value());
1159 return Either.left(result);
1162 public Either<List<CatalogComponent>, StorageOperationStatus> getElementCatalogData() {
1163 List<CatalogComponent> results = new ArrayList<>();
1164 StopWatch stopWatch = new StopWatch();
1167 Either<Iterator<Vertex>, TitanOperationStatus> verticesEither = titanDao.getCatalogVerticies();
1168 if (verticesEither.isRight()) {
1169 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(verticesEither.right().value()));
1171 Iterator<Vertex> vertices = verticesEither.left().value();
1172 while (vertices.hasNext()) {
1173 Vertex vertex = vertices.next();
1174 VertexProperty<Object> property = vertex.property(GraphPropertiesDictionary.METADATA.getProperty());
1175 String json = (String) property.value();
1177 CatalogComponent catalogComponent = new CatalogComponent();
1178 Map<String, Object> metadatObj = JsonParserUtils.toMap(json);
1180 catalogComponent.setComponentType(ComponentTypeEnum.valueOf((String) metadatObj.get(JsonPresentationFields.COMPONENT_TYPE.getPresentation())));
1181 catalogComponent.setVersion((String) metadatObj.get(JsonPresentationFields.VERSION.getPresentation()));
1182 catalogComponent.setName((String) metadatObj.get(JsonPresentationFields.NAME.getPresentation()));
1183 catalogComponent.setIcon((String) metadatObj.get(JsonPresentationFields.ICON.getPresentation()));
1184 catalogComponent.setUniqueId((String) metadatObj.get(JsonPresentationFields.UNIQUE_ID.getPresentation()));
1185 catalogComponent.setLifecycleState((String) metadatObj.get(JsonPresentationFields.LIFECYCLE_STATE.getPresentation()));
1186 catalogComponent.setLastUpdateDate((Long) metadatObj.get(JsonPresentationFields.LAST_UPDATE_DATE.getPresentation()));
1187 catalogComponent.setDistributionStatus((String) metadatObj.get(JsonPresentationFields.DISTRIBUTION_STATUS.getPresentation()));
1188 Object resourceType = metadatObj.get(JsonPresentationFields.RESOURCE_TYPE.getPresentation());
1189 if (resourceType != null) {
1190 catalogComponent.setResourceType((String) resourceType);
1193 if (catalogComponent.getComponentType() == ComponentTypeEnum.SERVICE) {
1194 setServiceCategoryFromGraphV(vertex, catalogComponent);
1197 setResourceCategoryFromGraphV(vertex, catalogComponent);
1199 results.add(catalogComponent);
1203 String timeToFetchElements = stopWatch.prettyPrint();
1204 log.info("time to fetch all catalog elements: {}", timeToFetchElements);
1205 return Either.left(results);
1208 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes, JsonParseFlagEnum parseFlag) {
1209 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<>();
1210 Map<GraphPropertyEnum, Object> propertiesHasNotToMatch = new HashMap<>();
1211 propertiesToMatch.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1212 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1214 if (componentType == ComponentTypeEnum.RESOURCE) {
1215 propertiesToMatch.put(GraphPropertyEnum.IS_ABSTRACT, false);
1216 propertiesHasNotToMatch.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1218 propertiesHasNotToMatch.put(GraphPropertyEnum.IS_DELETED, true);
1220 return titanDao.getByCriteria(null, propertiesToMatch, propertiesHasNotToMatch, parseFlag);
1223 // highest + (certified && !highest)
1224 public Either<List<GraphVertex>, TitanOperationStatus> getListOfHighestAndAllCertifiedComponents(ComponentTypeEnum componentType, List<ResourceTypeEnum> excludeTypes) {
1225 long startFetchAllStates = System.currentTimeMillis();
1226 Either<List<GraphVertex>, TitanOperationStatus> highestNodes = getListOfHighestComponents(componentType, excludeTypes, JsonParseFlagEnum.ParseMetadata);
1228 Map<GraphPropertyEnum, Object> propertiesToMatchCertified = new HashMap<>();
1229 Map<GraphPropertyEnum, Object> propertiesHasNotToMatchCertified = new HashMap<>();
1230 propertiesToMatchCertified.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
1231 propertiesToMatchCertified.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1232 if (componentType == ComponentTypeEnum.RESOURCE) {
1233 propertiesToMatchCertified.put(GraphPropertyEnum.IS_ABSTRACT, false);
1234 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.RESOURCE_TYPE, excludeTypes);
1237 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_DELETED, true);
1238 propertiesHasNotToMatchCertified.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
1240 Either<List<GraphVertex>, TitanOperationStatus> certifiedNotHighestNodes = titanDao.getByCriteria(null, propertiesToMatchCertified, propertiesHasNotToMatchCertified, JsonParseFlagEnum.ParseMetadata);
1241 if (certifiedNotHighestNodes.isRight() && certifiedNotHighestNodes.right().value() != TitanOperationStatus.NOT_FOUND) {
1242 return Either.right(certifiedNotHighestNodes.right().value());
1245 long endFetchAllStates = System.currentTimeMillis();
1247 List<GraphVertex> allNodes = new ArrayList<>();
1249 if (certifiedNotHighestNodes.isLeft()) {
1250 allNodes.addAll(certifiedNotHighestNodes.left().value());
1252 if (highestNodes.isLeft()) {
1253 allNodes.addAll(highestNodes.left().value());
1256 log.debug("Fetch catalog {}s all states from graph took {} ms", componentType, endFetchAllStates - startFetchAllStates);
1257 return Either.left(allNodes);
1260 protected Either<List<GraphVertex>, StorageOperationStatus> getAllComponentsMarkedForDeletion(ComponentTypeEnum componentType) {
1262 // get all components marked for delete
1263 Map<GraphPropertyEnum, Object> props = new HashMap<GraphPropertyEnum, Object>();
1264 props.put(GraphPropertyEnum.IS_DELETED, true);
1265 props.put(GraphPropertyEnum.COMPONENT_TYPE, componentType.name());
1267 Either<List<GraphVertex>, TitanOperationStatus> componentsToDelete = titanDao.getByCriteria(null, props, JsonParseFlagEnum.NoParse);
1269 if (componentsToDelete.isRight()) {
1270 TitanOperationStatus error = componentsToDelete.right().value();
1271 if (error.equals(TitanOperationStatus.NOT_FOUND)) {
1272 log.trace("no components to delete");
1273 return Either.left(new ArrayList<>());
1275 log.info("failed to find components to delete. error : {}", error.name());
1276 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error));
1279 return Either.left(componentsToDelete.left().value());
1282 protected TitanOperationStatus setAdditionalInformationFromGraph(GraphVertex componentV, ToscaElement toscaElement) {
1283 Either<Map<String, AdditionalInfoParameterDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ADDITIONAL_INFORMATION);
1284 if (result.isLeft()) {
1285 toscaElement.setAdditionalInformation(result.left().value());
1287 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
1288 return result.right().value();
1291 return TitanOperationStatus.OK;
1294 // --------------------------------------------
1295 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView);
1297 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> getToscaElement(GraphVertex toscaElementVertex, ComponentParametersView componentParametersView);
1299 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex);
1301 public abstract <T extends ToscaElement> Either<T, StorageOperationStatus> createToscaElement(ToscaElement toscaElement);
1303 protected abstract <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement);
1305 protected abstract <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement);
1307 protected abstract <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement);
1309 protected abstract <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV);
1311 protected abstract <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex updateElementV);
1313 public abstract <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag);