1 package org.openecomp.sdc.be.model.jsontitan.operations;
5 import org.apache.commons.lang3.tuple.ImmutablePair;
6 import org.apache.commons.lang3.tuple.ImmutableTriple;
7 import org.apache.tinkerpop.gremlin.structure.Direction;
8 import org.apache.tinkerpop.gremlin.structure.Edge;
9 import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
10 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
11 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
12 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
13 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
14 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
15 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
16 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
17 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
18 import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
19 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
20 import org.openecomp.sdc.be.datatypes.elements.MapCapabiltyProperty;
21 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
22 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
23 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
24 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
25 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
26 import org.openecomp.sdc.be.model.ComponentParametersView;
27 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
28 import org.openecomp.sdc.be.model.LifecycleStateEnum;
29 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
30 import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate;
31 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
32 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
33 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
34 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
35 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
36 import org.openecomp.sdc.be.resources.data.AttributeData;
37 import org.openecomp.sdc.be.resources.data.AttributeValueData;
38 import org.openecomp.sdc.be.resources.data.CapabilityData;
39 import org.openecomp.sdc.be.resources.data.CapabilityTypeData;
40 import org.openecomp.sdc.be.resources.data.DataTypeData;
41 import org.openecomp.sdc.be.resources.data.GroupData;
42 import org.openecomp.sdc.be.resources.data.GroupTypeData;
43 import org.openecomp.sdc.be.resources.data.InputValueData;
44 import org.openecomp.sdc.be.resources.data.InputsData;
45 import org.openecomp.sdc.be.resources.data.PolicyTypeData;
46 import org.openecomp.sdc.be.resources.data.PropertyData;
47 import org.openecomp.sdc.be.resources.data.PropertyValueData;
48 import org.openecomp.sdc.be.resources.data.RelationshipInstData;
49 import org.openecomp.sdc.be.resources.data.RelationshipTypeData;
50 import org.openecomp.sdc.be.resources.data.RequirementData;
51 import org.openecomp.sdc.be.resources.data.ResourceMetadataData;
52 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
53 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
54 import org.slf4j.Logger;
55 import org.slf4j.LoggerFactory;
56 import org.springframework.beans.factory.annotation.Qualifier;
58 import java.util.ArrayList;
59 import java.util.Collection;
60 import java.util.HashMap;
61 import java.util.List;
63 import java.util.Map.Entry;
64 import java.util.function.Function;
65 import java.util.regex.Pattern;
67 @org.springframework.stereotype.Component("node-type-operation")
68 public class NodeTypeOperation extends ToscaElementOperation {
69 public static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1");
70 public static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0");
72 private static Logger log = LoggerFactory.getLogger(NodeTypeOperation.class.getName());
74 private DerivedNodeTypeResolver derivedResourceResolver;
76 public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
77 this.derivedResourceResolver = derivedNodeTypeResolver;
80 public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
82 Either<NodeType, StorageOperationStatus> result = null;
84 nodeType.generateUUID();
86 nodeType = getResourceMetaDataFromResource(nodeType);
87 String resourceUniqueId = nodeType.getUniqueId();
88 if (resourceUniqueId == null) {
89 resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
90 nodeType.setUniqueId(resourceUniqueId);
93 // get derived from resources
94 List<GraphVertex> derivedResources = null;
95 Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
96 if (derivedResourcesResult.isRight()) {
97 result = Either.right(derivedResourcesResult.right().value());
100 derivedResources = derivedResourcesResult.left().value();
103 GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
104 fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
106 Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
107 if (createdVertex.isRight()) {
108 TitanOperationStatus status = createdVertex.right().value();
109 log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
110 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
113 nodeTypeVertex = createdVertex.left().value();
115 StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
116 if (assosiateCommon != StorageOperationStatus.OK) {
117 result = Either.right(assosiateCommon);
121 StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
122 if (associateDerived != StorageOperationStatus.OK) {
123 result = Either.right(associateDerived);
126 StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
127 if (associateCategory != StorageOperationStatus.OK) {
128 result = Either.right(associateCategory);
132 StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
133 if (associateAttributes != StorageOperationStatus.OK) {
134 result = Either.right(associateAttributes);
138 StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
139 if (associateRequirements != StorageOperationStatus.OK) {
140 result = Either.right(associateRequirements);
144 StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
145 if (associateCapabilities != StorageOperationStatus.OK) {
146 result = Either.right(associateCapabilities);
149 StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
150 if (associateCapabilitiesProps != StorageOperationStatus.OK) {
151 result = Either.right(associateCapabilitiesProps);
155 StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
156 if (associateInterfaces != StorageOperationStatus.OK) {
157 result = Either.right(associateInterfaces);
161 StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
162 if (addAdditionalInformation != StorageOperationStatus.OK) {
163 result = Either.right(addAdditionalInformation);
166 result = Either.left(nodeType);
171 private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
172 // Note : currently only one derived supported!!!!
173 Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
174 if (dataFromDerived.isRight()) {
175 return dataFromDerived.right().value();
177 Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
179 Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
180 if (interfacArts != null) {
181 interfacArtsAll.putAll(interfacArts);
183 if (!interfacArtsAll.isEmpty()) {
184 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
185 if (assosiateElementToData.isRight()) {
186 return assosiateElementToData.right().value();
189 return StorageOperationStatus.OK;
193 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
195 Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NodeType, JsonParseFlagEnum.ParseMetadata);
196 if (componentByLabelAndId.isRight()) {
197 return Either.right(componentByLabelAndId.right().value());
199 GraphVertex componentV = componentByLabelAndId.left().value();
201 return getToscaElement(componentV, componentParametersView);
205 // -------------------------------------------------------------
207 public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
208 NodeType toscaElement;
209 toscaElement = convertToComponent(componentV);
210 TitanOperationStatus status = null;
211 if (false == componentParametersView.isIgnoreUsers()) {
212 status = setCreatorFromGraph(componentV, toscaElement);
213 if (status != TitanOperationStatus.OK) {
214 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
217 status = setLastModifierFromGraph(componentV, toscaElement);
218 if (status != TitanOperationStatus.OK) {
219 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
223 if (false == componentParametersView.isIgnoreProperties()) {
224 status = setResourcePropertiesFromGraph(componentV, toscaElement);
225 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
226 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
230 if (false == componentParametersView.isIgnoreAttributesFrom()) {
231 status = setResourceAttributesFromGraph(componentV, toscaElement);
232 if (status != TitanOperationStatus.OK) {
233 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
237 if (false == componentParametersView.isIgnoreDerivedFrom()) {
238 status = setResourceDerivedFromGraph(componentV, toscaElement);
239 if (status != TitanOperationStatus.OK) {
240 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
244 if (false == componentParametersView.isIgnoreCategories()) {
245 status = setResourceCategoryFromGraph(componentV, toscaElement);
246 if (status != TitanOperationStatus.OK) {
247 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
250 if (false == componentParametersView.isIgnoreRequirements()) {
251 status = setResourceRequirementsFromGraph(componentV, toscaElement);
252 if (status != TitanOperationStatus.OK) {
253 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
254 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
257 if (false == componentParametersView.isIgnoreCapabilities()) {
258 status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
259 if (status != TitanOperationStatus.OK) {
260 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
264 if (false == componentParametersView.isIgnoreArtifacts()) {
265 status = setArtifactsFromGraph(componentV, toscaElement);
266 if (status != TitanOperationStatus.OK) {
267 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
270 if (false == componentParametersView.isIgnoreAdditionalInformation()) {
271 status = setAdditionalInformationFromGraph(componentV, toscaElement);
272 if (status != TitanOperationStatus.OK) {
273 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
276 if (false == componentParametersView.isIgnoreInterfaces()) {
277 status = setInterfacesFromGraph(componentV, toscaElement);
278 if (status != TitanOperationStatus.OK) {
279 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
282 if (false == componentParametersView.isIgnoreAllVersions()) {
283 status = setAllVersions(componentV, toscaElement);
284 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
285 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
289 if (false == componentParametersView.isIgnoreCapabiltyProperties()) {
290 status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
291 if (status != TitanOperationStatus.OK) {
292 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
296 return Either.left(toscaElement);
299 private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
300 Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
301 if (result.isLeft()) {
302 toscaElement.setCapabiltiesProperties(result.left().value());
304 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
305 return result.right().value();
308 return TitanOperationStatus.OK;
311 private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
312 Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
313 if (result.isLeft()) {
314 toscaElement.setInterfaceArtifacts(result.left().value());
316 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
317 return result.right().value();
320 return TitanOperationStatus.OK;
323 protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
324 return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
327 private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
328 Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
329 if (result.isLeft()) {
330 toscaElement.setCapabilties(result.left().value());
332 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
333 return result.right().value();
336 return TitanOperationStatus.OK;
339 private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
340 List<String> derivedFromList = new ArrayList<String>();
342 TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
343 if (TitanOperationStatus.OK != listFromGraphStatus) {
344 return listFromGraphStatus;
347 if (false == derivedFromList.isEmpty()) {
348 if (derivedFromList.size() > 1) {
349 List<String> lastDerivedFrom = new ArrayList<String>();
350 lastDerivedFrom.add(derivedFromList.get(1));
351 toscaElement.setDerivedFrom(lastDerivedFrom);
352 toscaElement.setDerivedList(derivedFromList);
354 toscaElement.setDerivedFrom(null);
355 toscaElement.setDerivedList(derivedFromList);
359 return TitanOperationStatus.OK;
362 protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
363 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
364 resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
365 while (parentResourceRes.isLeft()) {
367 GraphVertex parent = parentResourceRes.left().value();
368 resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
369 parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
371 TitanOperationStatus operationStatus = parentResourceRes.right().value();
373 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
374 return operationStatus;
376 return TitanOperationStatus.OK;
381 protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
382 return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
385 private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
386 Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
387 if (result.isLeft()) {
388 toscaElement.setRequirements(result.left().value());
390 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
391 return result.right().value();
394 return TitanOperationStatus.OK;
397 private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
398 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
399 if (result.isLeft()) {
400 toscaElement.setAttributes(result.left().value());
402 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
403 return result.right().value();
406 return TitanOperationStatus.OK;
409 private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
410 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
411 if (result.isLeft()) {
412 toscaElement.setProperties(result.left().value());
414 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
415 return result.right().value();
418 return TitanOperationStatus.OK;
421 private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
422 for (GraphVertex derivedV : derivedResources) {
423 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
424 if (createEdge != TitanOperationStatus.OK) {
425 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
426 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
429 return StorageOperationStatus.OK;
432 private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
433 // Note : currently only one derived supported!!!!
434 Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
435 if (dataFromDerived.isRight()) {
436 return dataFromDerived.right().value();
438 Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
440 Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
441 if (addInformation != null) {
442 ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
444 if (!addInformationAll.isEmpty()) {
445 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
446 if (assosiateElementToData.isRight()) {
447 return assosiateElementToData.right().value();
450 return StorageOperationStatus.OK;
453 private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
454 // Note : currently only one derived supported!!!!
455 Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
456 if (dataFromDerived.isRight()) {
457 return dataFromDerived.right().value();
459 Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
461 Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
462 if (capabilties != null) {
463 if (capabiltiesAll == null) {
464 capabiltiesAll = new HashMap<>();
466 capabilties.values().forEach(l -> {
467 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
468 String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
473 ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
475 if (!capabiltiesAll.isEmpty()) {
476 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
477 if (assosiateElementToData.isRight()) {
478 return assosiateElementToData.right().value();
481 return StorageOperationStatus.OK;
484 private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
485 // Note : currently only one derived supported!!!!
486 Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
487 if (dataFromDerived.isRight()) {
488 return dataFromDerived.right().value();
490 Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
492 Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
493 if (requirements != null) {
494 if (requirementsAll == null) {
495 requirementsAll = new HashMap<>();
497 requirements.values().forEach(l -> {
498 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
499 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
504 ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
507 if (!requirementsAll.isEmpty()) {
508 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
509 if (assosiateElementToData.isRight()) {
510 return assosiateElementToData.right().value();
513 return StorageOperationStatus.OK;
516 private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
517 // Note : currently only one derived supported!!!!
518 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
519 if (dataFromDerived.isRight()) {
520 return dataFromDerived.right().value();
522 Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
524 Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
525 if (attributes != null) {
526 attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
527 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
530 ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
532 if (!attributesAll.isEmpty()) {
533 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
534 if (assosiateElementToData.isRight()) {
535 return assosiateElementToData.right().value();
538 return StorageOperationStatus.OK;
541 // TODO get from derived
542 private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
543 // // Note : currently only one derived supported!!!!
544 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
545 if (dataFromDerived.isRight()) {
546 return dataFromDerived.right().value();
548 Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
549 Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
550 if (capabiltiesProps != null) {
551 capabiltiesProps.values().forEach(l -> {
552 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
553 Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
554 mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
555 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
560 ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
562 if (!propertiesAll.isEmpty()) {
563 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
564 if (assosiateElementToData.isRight()) {
565 return assosiateElementToData.right().value();
568 return StorageOperationStatus.OK;
571 public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
573 List<GraphVertex> derivedResources = new ArrayList<GraphVertex>();
574 List<String> derivedFromResources = nodeType.getDerivedFrom();
575 if (derivedFromResources != null && false == derivedFromResources.isEmpty()) {
577 for (String parentResource : derivedFromResources) {
578 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
579 List<GraphVertex> resources = null;
580 if (getParentResources.isRight()) {
581 log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
582 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
585 resources = getParentResources.left().value();
586 if (resources == null || resources.size() == 0) {
587 log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
588 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
590 if (resources.size() > 1) {
591 log.error("Multiple parent resources called {} found in the graph.", parentResource);
592 return Either.right(StorageOperationStatus.MULTIPLE_PARENT_RESOURCE_FOUND);
594 GraphVertex parentResourceData = resources.get(0);
595 derivedResources.add(parentResourceData);
602 return Either.left(derivedResources);
605 private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
606 nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
608 fillCommonMetadata(nodeTypeVertex, nodeType);
610 return nodeTypeVertex;
614 public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
615 Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
616 if (nodeType.isRight()) {
617 log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
620 TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
621 if (status != TitanOperationStatus.OK) {
622 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
624 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
625 if (status != TitanOperationStatus.OK) {
626 log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
627 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
629 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
630 if (status != TitanOperationStatus.OK) {
631 log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
632 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
634 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
635 if (status != TitanOperationStatus.OK) {
636 log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
637 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
639 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
640 if (status != TitanOperationStatus.OK) {
641 log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
642 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
644 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
645 if (status != TitanOperationStatus.OK) {
646 log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
647 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
649 toscaElementVertex.getVertex().remove();
650 log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
655 @SuppressWarnings("unchecked")
657 public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
658 return createNodeType((NodeType) toscaElement);
662 protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
663 return setResourceCategoryFromGraph(vertexComponent, toscaElement);
667 protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
668 return validateResourceCategory(toscaElementToUpdate, elementV);
672 protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
674 NodeType nodeType = (NodeType) toscaElementToUpdate;
675 List<GraphVertex> derivedResources = new ArrayList<>();
677 List<String> derivedFromResources = nodeType.getDerivedFrom();
679 // now supported only single derived from
680 if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
681 String firstDerived = derivedFromResources.get(0);
682 boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
683 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
684 if (childVertex.isRight()) {
685 TitanOperationStatus getchieldError = childVertex.right().value();
686 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
687 return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
689 GraphVertex firstDerivedInChain = childVertex.left().value();
691 String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
692 if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
694 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
695 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
697 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
698 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
700 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
702 if (getParentResources.isRight()) {
703 TitanOperationStatus error = getParentResources.right().value();
704 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
705 return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
708 GraphVertex newDerived = getParentResources.left().value().get(0);
709 derivedResources.add(newDerived);
710 StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType)toscaElementToUpdate);
711 if (updateStatus != StorageOperationStatus.OK) {
712 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerived.getUniqueId(), updateStatus);
716 Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, firstDerivedInChain, EdgeLabelEnum.DERIVED_FROM);
717 if (deleteEdge.isRight()) {
718 TitanOperationStatus deleteError = deleteEdge.right().value();
719 log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), firstDerivedInChain.getUniqueId(), deleteError);
720 return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
723 titanDao.createEdge(nodeTypeV, newDerived, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
727 return StorageOperationStatus.OK;
730 private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
734 return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
736 return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
738 return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
740 return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
741 case ADDITIONAL_INFORMATION:
742 return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
743 case CAPABILITIES_PROPERTIES:
744 return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
746 return StorageOperationStatus.OK;
751 private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate) {
753 StorageOperationStatus status = updateDataByType(newDerived, nodeTypeV, EdgeLabelEnum.CAPABILITIES, nodeToUpdate);
754 if (status != StorageOperationStatus.OK) {
758 status = updateDataByType(newDerived, nodeTypeV, EdgeLabelEnum.REQUIREMENTS, nodeToUpdate);
759 if (status != StorageOperationStatus.OK) {
763 status = updateDataByType(newDerived, nodeTypeV, EdgeLabelEnum.PROPERTIES, nodeToUpdate);
764 if (status != StorageOperationStatus.OK) {
768 status = updateDataByType(newDerived, nodeTypeV, EdgeLabelEnum.ATTRIBUTES, nodeToUpdate);
769 if (status != StorageOperationStatus.OK) {
773 status = updateDataByType(newDerived, nodeTypeV,EdgeLabelEnum.CAPABILITIES_PROPERTIES, nodeToUpdate);
774 if (status != StorageOperationStatus.OK) {
777 status = updateDataByType(newDerived, nodeTypeV, EdgeLabelEnum.ADDITIONAL_INFORMATION, nodeToUpdate);
781 private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement) {
782 log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
783 Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
784 if (dataFromGraph.isRight()) {
785 if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
786 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
787 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
789 GraphVertex dataV = dataFromGraph.left().value();
791 Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
792 mapFromGraph.entrySet().removeIf(e -> e.getValue().getOwnerId() != null);
795 Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
796 if (dataFromDerived.isRight()) {
797 return dataFromDerived.right().value();
799 Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
801 Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
802 if(merged.isRight()){
803 log.debug("property {} cannot be overriden", merged.right().value());
804 return StorageOperationStatus.INVALID_PROPERTY;
806 dataV.setJson(dataFromDerivedAll);
807 Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
808 if (updateDataV.isRight()) {
809 return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
811 return StorageOperationStatus.OK;
815 public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
816 fillMetadata(elementV, (NodeType) toscaElementToUpdate);