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 fj.data.Either;
25 import org.apache.tinkerpop.gremlin.structure.Direction;
26 import org.apache.tinkerpop.gremlin.structure.Edge;
27 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
28 import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum;
29 import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum;
30 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
31 import org.openecomp.sdc.be.dao.titan.TitanOperationStatus;
32 import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition;
33 import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
34 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
35 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
36 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
37 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
38 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
39 import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition;
40 import org.openecomp.sdc.be.model.ComponentParametersView;
41 import org.openecomp.sdc.be.model.DerivedNodeTypeResolver;
42 import org.openecomp.sdc.be.model.LifecycleStateEnum;
43 import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType;
44 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement;
45 import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum;
46 import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
47 import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter;
48 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
49 import org.openecomp.sdc.common.jsongraph.util.CommonUtility;
50 import org.openecomp.sdc.common.jsongraph.util.CommonUtility.LogLevelEnum;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.springframework.beans.factory.annotation.Qualifier;
55 import java.util.ArrayList;
56 import java.util.Collection;
57 import java.util.Collections;
58 import java.util.EnumSet;
59 import java.util.HashMap;
60 import java.util.List;
62 import java.util.regex.Pattern;
64 @org.springframework.stereotype.Component("node-type-operation")
65 public class NodeTypeOperation extends ToscaElementOperation {
66 public static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1");
67 public static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0");
69 private static Logger log = LoggerFactory.getLogger(NodeTypeOperation.class.getName());
71 private DerivedNodeTypeResolver derivedResourceResolver;
73 public NodeTypeOperation(@Qualifier("derived-resource-resolver") DerivedNodeTypeResolver derivedNodeTypeResolver) {
74 this.derivedResourceResolver = derivedNodeTypeResolver;
77 public Either<NodeType, StorageOperationStatus> createNodeType(NodeType nodeType) {
79 Either<NodeType, StorageOperationStatus> result = null;
81 nodeType.generateUUID();
83 nodeType = getResourceMetaDataFromResource(nodeType);
84 String resourceUniqueId = nodeType.getUniqueId();
85 if (resourceUniqueId == null) {
86 resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId();
87 nodeType.setUniqueId(resourceUniqueId);
90 // get derived from resources
91 List<GraphVertex> derivedResources = null;
92 Either<List<GraphVertex>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(nodeType);
93 if (derivedResourcesResult.isRight()) {
94 result = Either.right(derivedResourcesResult.right().value());
97 derivedResources = derivedResourcesResult.left().value();
100 GraphVertex nodeTypeVertex = new GraphVertex(VertexTypeEnum.NODE_TYPE);
101 fillToscaElementVertexData(nodeTypeVertex, nodeType, JsonParseFlagEnum.ParseAll);
103 Either<GraphVertex, TitanOperationStatus> createdVertex = titanDao.createVertex(nodeTypeVertex);
104 if (createdVertex.isRight()) {
105 TitanOperationStatus status = createdVertex.right().value();
106 log.error("Error returned after creating resource data node {}. status returned is ", nodeTypeVertex, status);
107 result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
110 nodeTypeVertex = createdVertex.left().value();
112 StorageOperationStatus assosiateCommon = assosiateCommonForToscaElement(nodeTypeVertex, nodeType, derivedResources);
113 if (assosiateCommon != StorageOperationStatus.OK) {
114 result = Either.right(assosiateCommon);
118 StorageOperationStatus associateDerived = assosiateToDerived(nodeTypeVertex, derivedResources);
119 if (associateDerived != StorageOperationStatus.OK) {
120 result = Either.right(associateDerived);
123 StorageOperationStatus associateCategory = assosiateResourceMetadataToCategory(nodeTypeVertex, nodeType);
124 if (associateCategory != StorageOperationStatus.OK) {
125 result = Either.right(associateCategory);
129 StorageOperationStatus associateAttributes = associateAttributesToResource(nodeTypeVertex, nodeType, derivedResources);
130 if (associateAttributes != StorageOperationStatus.OK) {
131 result = Either.right(associateAttributes);
135 StorageOperationStatus associateRequirements = associateRequirementsToResource(nodeTypeVertex, nodeType, derivedResources);
136 if (associateRequirements != StorageOperationStatus.OK) {
137 result = Either.right(associateRequirements);
141 StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(nodeTypeVertex, nodeType, derivedResources);
142 if (associateCapabilities != StorageOperationStatus.OK) {
143 result = Either.right(associateCapabilities);
146 StorageOperationStatus associateCapabilitiesProps = associateCapabilitiesPropertiesToResource(nodeTypeVertex, nodeType, derivedResources);
147 if (associateCapabilitiesProps != StorageOperationStatus.OK) {
148 result = Either.right(associateCapabilitiesProps);
152 StorageOperationStatus associateInterfaces = associateInterfacesToResource(nodeTypeVertex, nodeType, derivedResources);
153 if (associateInterfaces != StorageOperationStatus.OK) {
154 result = Either.right(associateInterfaces);
158 StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(nodeTypeVertex, nodeType, derivedResources);
159 if (addAdditionalInformation != StorageOperationStatus.OK) {
160 result = Either.right(addAdditionalInformation);
163 result = Either.left(nodeType);
168 private StorageOperationStatus associateInterfacesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
169 // Note : currently only one derived supported!!!!
170 Either<Map<String, InterfaceDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.INTERFACE_ARTIFACTS);
171 if (dataFromDerived.isRight()) {
172 return dataFromDerived.right().value();
174 Map<String, InterfaceDataDefinition> interfacArtsAll = dataFromDerived.left().value();
176 Map<String, InterfaceDataDefinition> interfacArts = nodeType.getInterfaceArtifacts();
177 if (interfacArts != null) {
178 interfacArtsAll.putAll(interfacArts);
180 if (!interfacArtsAll.isEmpty()) {
181 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.INTERFACE_ARTIFACTS, EdgeLabelEnum.INTERFACE_ARTIFACTS, interfacArtsAll);
182 if (assosiateElementToData.isRight()) {
183 return assosiateElementToData.right().value();
186 return StorageOperationStatus.OK;
190 public Either<ToscaElement, StorageOperationStatus> getToscaElement(String uniqueId, ComponentParametersView componentParametersView) {
192 Either<GraphVertex, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, ToscaElementTypeEnum.NodeType, JsonParseFlagEnum.ParseMetadata);
193 if (componentByLabelAndId.isRight()) {
194 return Either.right(componentByLabelAndId.right().value());
196 GraphVertex componentV = componentByLabelAndId.left().value();
198 return getToscaElement(componentV, componentParametersView);
202 // -------------------------------------------------------------
204 public Either<ToscaElement, StorageOperationStatus> getToscaElement(GraphVertex componentV, ComponentParametersView componentParametersView) {
205 NodeType toscaElement;
206 toscaElement = convertToComponent(componentV);
207 TitanOperationStatus status = null;
208 if (false == componentParametersView.isIgnoreUsers()) {
209 status = setCreatorFromGraph(componentV, toscaElement);
210 if (status != TitanOperationStatus.OK) {
211 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
214 status = setLastModifierFromGraph(componentV, toscaElement);
215 if (status != TitanOperationStatus.OK) {
216 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
220 if (false == componentParametersView.isIgnoreProperties()) {
221 status = setResourcePropertiesFromGraph(componentV, toscaElement);
222 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
223 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
227 if (false == componentParametersView.isIgnoreAttributesFrom()) {
228 status = setResourceAttributesFromGraph(componentV, toscaElement);
229 if (status != TitanOperationStatus.OK) {
230 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
234 if (false == componentParametersView.isIgnoreDerivedFrom()) {
235 status = setResourceDerivedFromGraph(componentV, toscaElement);
236 if (status != TitanOperationStatus.OK) {
237 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
241 if (false == componentParametersView.isIgnoreCategories()) {
242 status = setResourceCategoryFromGraph(componentV, toscaElement);
243 if (status != TitanOperationStatus.OK) {
244 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
247 if (false == componentParametersView.isIgnoreRequirements()) {
248 status = setResourceRequirementsFromGraph(componentV, toscaElement);
249 if (status != TitanOperationStatus.OK) {
250 log.error("Failed to set requirement of resource {}. status is {}", componentV.getUniqueId(), status);
251 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
254 if (false == componentParametersView.isIgnoreCapabilities()) {
255 status = setResourceCapabilitiesFromGraph(componentV, toscaElement);
256 if (status != TitanOperationStatus.OK) {
257 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
261 if (false == componentParametersView.isIgnoreArtifacts()) {
262 status = setArtifactsFromGraph(componentV, toscaElement);
263 if (status != TitanOperationStatus.OK) {
264 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
267 if (false == componentParametersView.isIgnoreAdditionalInformation()) {
268 status = setAdditionalInformationFromGraph(componentV, toscaElement);
269 if (status != TitanOperationStatus.OK) {
270 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
273 if (false == componentParametersView.isIgnoreInterfaces()) {
274 status = setInterfacesFromGraph(componentV, toscaElement);
275 if (status != TitanOperationStatus.OK) {
276 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
279 if (false == componentParametersView.isIgnoreAllVersions()) {
280 status = setAllVersions(componentV, toscaElement);
281 if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) {
282 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
286 if (false == componentParametersView.isIgnoreCapabiltyProperties()) {
287 status = setComponentCapPropertiesFromGraph(componentV, toscaElement);
288 if (status != TitanOperationStatus.OK) {
289 return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
293 return Either.left(toscaElement);
296 private TitanOperationStatus setComponentCapPropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
297 Either<Map<String, MapPropertiesDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
298 if (result.isLeft()) {
299 toscaElement.setCapabiltiesProperties(result.left().value());
301 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
302 return result.right().value();
305 return TitanOperationStatus.OK;
308 private TitanOperationStatus setInterfacesFromGraph(GraphVertex componentV, NodeType toscaElement) {
309 Either<Map<String, InterfaceDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.INTERFACE_ARTIFACTS);
310 if (result.isLeft()) {
311 toscaElement.setInterfaceArtifacts(result.left().value());
313 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
314 return result.right().value();
317 return TitanOperationStatus.OK;
320 protected <T extends ToscaElement> TitanOperationStatus setCapabilitiesFromGraph(GraphVertex componentV, T toscaElement) {
321 return setResourceCapabilitiesFromGraph(componentV, (NodeType) toscaElement);
324 private TitanOperationStatus setResourceCapabilitiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
325 Either<Map<String, ListCapabilityDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES);
326 if (result.isLeft()) {
327 toscaElement.setCapabilties(result.left().value());
329 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
330 return result.right().value();
333 return TitanOperationStatus.OK;
336 private TitanOperationStatus setResourceDerivedFromGraph(GraphVertex componentV, NodeType toscaElement) {
337 List<String> derivedFromList = new ArrayList<String>();
339 TitanOperationStatus listFromGraphStatus = findResourcesPathRecursively(componentV, derivedFromList);
340 if (TitanOperationStatus.OK != listFromGraphStatus) {
341 return listFromGraphStatus;
344 if (false == derivedFromList.isEmpty()) {
345 if (derivedFromList.size() > 1) {
346 List<String> lastDerivedFrom = new ArrayList<String>();
347 lastDerivedFrom.add(derivedFromList.get(1));
348 toscaElement.setDerivedFrom(lastDerivedFrom);
349 toscaElement.setDerivedList(derivedFromList);
351 toscaElement.setDerivedFrom(null);
352 toscaElement.setDerivedList(derivedFromList);
356 return TitanOperationStatus.OK;
359 protected TitanOperationStatus findResourcesPathRecursively(GraphVertex nodeTypeV, List<String> resourcesPathList) {
360 Either<GraphVertex, TitanOperationStatus> parentResourceRes = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
361 resourcesPathList.add((String) nodeTypeV.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
362 while (parentResourceRes.isLeft()) {
364 GraphVertex parent = parentResourceRes.left().value();
365 resourcesPathList.add((String) parent.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME));
366 parentResourceRes = titanDao.getChildVertex(parent, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
368 TitanOperationStatus operationStatus = parentResourceRes.right().value();
370 if (operationStatus != TitanOperationStatus.NOT_FOUND) {
371 return operationStatus;
373 return TitanOperationStatus.OK;
378 protected <T extends ToscaElement> TitanOperationStatus setRequirementsFromGraph(GraphVertex componentV, T toscaElement) {
379 return setResourceRequirementsFromGraph(componentV, (NodeType) toscaElement);
382 private TitanOperationStatus setResourceRequirementsFromGraph(GraphVertex componentV, NodeType toscaElement) {
383 Either<Map<String, ListRequirementDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.REQUIREMENTS);
384 if (result.isLeft()) {
385 toscaElement.setRequirements(result.left().value());
387 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
388 return result.right().value();
391 return TitanOperationStatus.OK;
394 private TitanOperationStatus setResourceAttributesFromGraph(GraphVertex componentV, NodeType toscaElement) {
395 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.ATTRIBUTES);
396 if (result.isLeft()) {
397 toscaElement.setAttributes(result.left().value());
399 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
400 return result.right().value();
403 return TitanOperationStatus.OK;
406 private TitanOperationStatus setResourcePropertiesFromGraph(GraphVertex componentV, NodeType toscaElement) {
407 Either<Map<String, PropertyDataDefinition>, TitanOperationStatus> result = getDataFromGraph(componentV, EdgeLabelEnum.PROPERTIES);
408 if (result.isLeft()) {
409 toscaElement.setProperties(result.left().value());
411 if (result.right().value() != TitanOperationStatus.NOT_FOUND) {
412 return result.right().value();
415 return TitanOperationStatus.OK;
418 private StorageOperationStatus assosiateToDerived(GraphVertex nodeTypeVertex, List<GraphVertex> derivedResources) {
419 for (GraphVertex derivedV : derivedResources) {
420 TitanOperationStatus createEdge = titanDao.createEdge(nodeTypeVertex, derivedV, EdgeLabelEnum.DERIVED_FROM, null);
421 if (createEdge != TitanOperationStatus.OK) {
422 log.trace("Failed to associate resource {} to derived with id {}", nodeTypeVertex.getUniqueId(), derivedV.getUniqueId());
423 return DaoStatusConverter.convertTitanStatusToStorageStatus(createEdge);
426 return StorageOperationStatus.OK;
429 private StorageOperationStatus addAdditionalInformationToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
430 // Note : currently only one derived supported!!!!
431 Either<Map<String, AdditionalInfoParameterDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ADDITIONAL_INFORMATION);
432 if (dataFromDerived.isRight()) {
433 return dataFromDerived.right().value();
435 Map<String, AdditionalInfoParameterDataDefinition> addInformationAll = dataFromDerived.left().value();
437 Map<String, AdditionalInfoParameterDataDefinition> addInformation = nodeType.getAdditionalInformation();
438 if (addInformation != null) {
439 ToscaDataDefinition.mergeDataMaps(addInformationAll, addInformation);
441 if (!addInformationAll.isEmpty()) {
442 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ADDITIONAL_INFORMATION, EdgeLabelEnum.ADDITIONAL_INFORMATION, addInformationAll);
443 if (assosiateElementToData.isRight()) {
444 return assosiateElementToData.right().value();
447 return StorageOperationStatus.OK;
450 private StorageOperationStatus associateCapabilitiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
451 // Note : currently only one derived supported!!!!
452 Either<Map<String, ListCapabilityDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES);
453 if (dataFromDerived.isRight()) {
454 return dataFromDerived.right().value();
456 Map<String, ListCapabilityDataDefinition> capabiltiesAll = dataFromDerived.left().value();
458 Map<String, ListCapabilityDataDefinition> capabilties = nodeType.getCapabilties();
459 if (capabilties != null) {
460 if (capabiltiesAll == null) {
461 capabiltiesAll = new HashMap<>();
463 capabilties.values().forEach(l -> {
464 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
465 String uid = UniqueIdBuilder.buildCapabilityUid(nodeTypeVertex.getUniqueId(), p.getName());
470 ToscaDataDefinition.mergeDataMaps(capabiltiesAll, capabilties);
472 if (!capabiltiesAll.isEmpty()) {
473 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILTIES, EdgeLabelEnum.CAPABILITIES, capabiltiesAll);
474 if (assosiateElementToData.isRight()) {
475 return assosiateElementToData.right().value();
478 return StorageOperationStatus.OK;
481 private StorageOperationStatus associateRequirementsToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
482 // Note : currently only one derived supported!!!!
483 Either<Map<String, ListRequirementDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.REQUIREMENTS);
484 if (dataFromDerived.isRight()) {
485 return dataFromDerived.right().value();
487 Map<String, ListRequirementDataDefinition> requirementsAll = dataFromDerived.left().value();
489 Map<String, ListRequirementDataDefinition> requirements = nodeType.getRequirements();
490 if (requirements != null) {
491 if (requirementsAll == null) {
492 requirementsAll = new HashMap<>();
494 requirements.values().forEach(l -> {
495 l.getListToscaDataDefinition().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
496 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
501 ToscaDataDefinition.mergeDataMaps(requirementsAll, requirements);
504 if (!requirementsAll.isEmpty()) {
505 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.REQUIREMENTS, EdgeLabelEnum.REQUIREMENTS, requirementsAll);
506 if (assosiateElementToData.isRight()) {
507 return assosiateElementToData.right().value();
510 return StorageOperationStatus.OK;
513 private StorageOperationStatus associateAttributesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
514 // Note : currently only one derived supported!!!!
515 Either<Map<String, PropertyDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.ATTRIBUTES);
516 if (dataFromDerived.isRight()) {
517 return dataFromDerived.right().value();
519 Map<String, PropertyDataDefinition> attributesAll = dataFromDerived.left().value();
521 Map<String, PropertyDataDefinition> attributes = nodeType.getAttributes();
522 if (attributes != null) {
523 attributes.values().stream().filter(p -> p.getUniqueId() == null).forEach(p -> {
524 String uid = UniqueIdBuilder.buildAttributeUid(nodeTypeVertex.getUniqueId(), p.getName());
527 ToscaDataDefinition.mergeDataMaps(attributesAll, attributes);
529 if (!attributesAll.isEmpty()) {
530 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.ATTRIBUTES, EdgeLabelEnum.ATTRIBUTES, attributesAll);
531 if (assosiateElementToData.isRight()) {
532 return assosiateElementToData.right().value();
535 return StorageOperationStatus.OK;
538 // TODO get from derived
539 private StorageOperationStatus associateCapabilitiesPropertiesToResource(GraphVertex nodeTypeVertex, NodeType nodeType, List<GraphVertex> derivedResources) {
540 // // Note : currently only one derived supported!!!!
541 Either<Map<String, MapPropertiesDataDefinition>, StorageOperationStatus> dataFromDerived = getDataFromDerived(derivedResources, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
542 if (dataFromDerived.isRight()) {
543 return dataFromDerived.right().value();
545 Map<String, MapPropertiesDataDefinition> propertiesAll = dataFromDerived.left().value();
546 Map<String, MapPropertiesDataDefinition> capabiltiesProps = nodeType.getCapabiltiesProperties();
547 if (capabiltiesProps != null) {
548 capabiltiesProps.values().forEach(l -> {
549 if (l.getMapToscaDataDefinition() != null && l.getMapToscaDataDefinition().values() != null) {
550 Collection<PropertyDataDefinition> mapToscaDataDefinition = l.getMapToscaDataDefinition().values();
551 mapToscaDataDefinition.stream().filter(p -> p != null && p.getUniqueId() == null).forEach(p -> {
552 String uid = UniqueIdBuilder.buildRequirementUid(nodeTypeVertex.getUniqueId(), p.getName());
557 ToscaDataDefinition.mergeDataMaps(propertiesAll, capabiltiesProps);
559 if (!propertiesAll.isEmpty()) {
560 Either<GraphVertex, StorageOperationStatus> assosiateElementToData = assosiateElementToData(nodeTypeVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, propertiesAll);
561 if (assosiateElementToData.isRight()) {
562 return assosiateElementToData.right().value();
565 return StorageOperationStatus.OK;
568 public Either<List<GraphVertex>, StorageOperationStatus> findDerivedResources(NodeType nodeType) {
570 List<GraphVertex> derivedResources = new ArrayList<GraphVertex>();
571 List<String> derivedFromResources = nodeType.getDerivedFrom();
572 if (derivedFromResources != null && false == derivedFromResources.isEmpty()) {
574 for (String parentResource : derivedFromResources) {
575 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = derivedResourceResolver.findDerivedResources(parentResource);
576 List<GraphVertex> resources = null;
577 if (getParentResources.isRight()) {
578 log.error("Cannot find parent resource by tosca resource name {} in the graph.", parentResource);
579 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
582 resources = getParentResources.left().value();
583 if (resources == null || resources.size() == 0) {
584 log.error("Cannot find parent resource by tosca name {} in the graph. resources size is empty", parentResource);
585 return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND);
587 if (resources.size() > 1) {
588 return handleMultipleParent(parentResource, derivedResources, resources);
590 GraphVertex parentResourceData = resources.get(0);
591 derivedResources.add(parentResourceData);
599 return Either.left(derivedResources);
602 Either<List<GraphVertex>, StorageOperationStatus> handleMultipleParent(String parentResource, List<GraphVertex> derivedResource, List<GraphVertex> fetchedDerivedResources){
604 Either<List<GraphVertex>, StorageOperationStatus> result = Either.left(derivedResource);
606 fetchedDerivedResources.sort((d1,d2)->{
607 return new Double(Double.parseDouble((String)d1.getMetadataProperty(GraphPropertyEnum.VERSION)))
608 .compareTo(Double.parseDouble((String)d2.getMetadataProperty(GraphPropertyEnum.VERSION)));
611 int actualHighestIndex = fetchedDerivedResources.size() - 1;
612 derivedResource.add(fetchedDerivedResources.get(actualHighestIndex));
613 fetchedDerivedResources.remove(actualHighestIndex);
615 StorageOperationStatus status = fixMultipleParent(fetchedDerivedResources);
616 if(status != StorageOperationStatus.OK){
617 result = Either.right(status);
619 } catch (Exception e){
620 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Exception occured during handle multiple parent {}. Exception is {}",
621 parentResource, e.getMessage());
622 result = Either.right(StorageOperationStatus.GENERAL_ERROR);
627 private StorageOperationStatus fixMultipleParent(List<GraphVertex> fetchedDerivedResources) {
628 StorageOperationStatus result = StorageOperationStatus.OK;
629 for(GraphVertex fetchedDerivedResource : fetchedDerivedResources){
630 fetchedDerivedResource.addMetadataProperty(GraphPropertyEnum.IS_HIGHEST_VERSION, false);
631 Either<GraphVertex, TitanOperationStatus> updateVertexRes = titanDao.updateVertex(fetchedDerivedResource);
632 if (updateVertexRes.isRight()) {
633 TitanOperationStatus titatStatus = updateVertexRes.right().value();
634 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to set highest version of node type {} to false. Status is {}",
635 fetchedDerivedResource.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME), titatStatus);
636 result = DaoStatusConverter.convertTitanStatusToStorageStatus(titatStatus);
643 private GraphVertex fillMetadata(GraphVertex nodeTypeVertex, NodeType nodeType) {
644 nodeTypeVertex.setLabel(VertexTypeEnum.NODE_TYPE);
646 fillCommonMetadata(nodeTypeVertex, nodeType);
648 return nodeTypeVertex;
652 public Either<ToscaElement, StorageOperationStatus> deleteToscaElement(GraphVertex toscaElementVertex) {
653 Either<ToscaElement, StorageOperationStatus> nodeType = getToscaElement(toscaElementVertex, new ComponentParametersView());
654 if (nodeType.isRight()) {
655 log.debug("Failed to fetch tosca element {} error {}", toscaElementVertex.getUniqueId(), nodeType.right().value());
658 TitanOperationStatus status = disassociateAndDeleteCommonElements(toscaElementVertex);
659 if (status != TitanOperationStatus.OK) {
660 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
662 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES);
663 if (status != TitanOperationStatus.OK) {
664 log.debug("Failed to disassociate capabilties for {} error {}", toscaElementVertex.getUniqueId(), status);
665 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
667 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES);
668 if (status != TitanOperationStatus.OK) {
669 log.debug("Failed to disassociate capabilties properties for {} error {}", toscaElementVertex.getUniqueId(), status);
670 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
672 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.REQUIREMENTS);
673 if (status != TitanOperationStatus.OK) {
674 log.debug("Failed to disassociate requirements for {} error {}", toscaElementVertex.getUniqueId(), status);
675 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
677 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.ATTRIBUTES);
678 if (status != TitanOperationStatus.OK) {
679 log.debug("Failed to disassociate attributes for {} error {}", toscaElementVertex.getUniqueId(), status);
680 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
682 status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.INTERFACE_ARTIFACTS);
683 if (status != TitanOperationStatus.OK) {
684 log.debug("Failed to disassociate interface artifacts for {} error {}", toscaElementVertex.getUniqueId(), status);
685 Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status));
687 toscaElementVertex.getVertex().remove();
688 log.trace("Tosca element vertex for {} was removed", toscaElementVertex.getUniqueId());
693 @SuppressWarnings("unchecked")
695 public Either<NodeType, StorageOperationStatus> createToscaElement(ToscaElement toscaElement) {
696 return createNodeType((NodeType) toscaElement);
700 protected <T extends ToscaElement> TitanOperationStatus setCategoriesFromGraph(GraphVertex vertexComponent, T toscaElement) {
701 return setResourceCategoryFromGraph(vertexComponent, toscaElement);
705 protected <T extends ToscaElement> StorageOperationStatus validateCategories(T toscaElementToUpdate, GraphVertex elementV) {
706 return validateResourceCategory(toscaElementToUpdate, elementV);
710 protected <T extends ToscaElement> StorageOperationStatus updateDerived(T toscaElementToUpdate, GraphVertex nodeTypeV) {
712 NodeType nodeType = (NodeType) toscaElementToUpdate;
713 List<GraphVertex> derivedResources = new ArrayList<>();
715 List<String> derivedFromResources = nodeType.getDerivedFrom();
717 // now supported only single derived from
718 if (derivedFromResources != null && !derivedFromResources.isEmpty() && derivedFromResources.get(0) != null) {
719 String firstDerived = derivedFromResources.get(0);
720 boolean derivedFromGenericType = null != nodeType.getDerivedFromGenericType();
721 Either<GraphVertex, TitanOperationStatus> childVertex = titanDao.getChildVertex(nodeTypeV, EdgeLabelEnum.DERIVED_FROM, JsonParseFlagEnum.NoParse);
722 if (childVertex.isRight()) {
723 TitanOperationStatus getchieldError = childVertex.right().value();
724 log.debug("Failed to fetch derived resource for element {} error {}", nodeTypeV.getUniqueId(), getchieldError);
725 return DaoStatusConverter.convertTitanStatusToStorageStatus(getchieldError);
727 GraphVertex firstDerivedInChain = childVertex.left().value();
729 String firstCurrentDerived = (String) firstDerivedInChain.getMetadataProperty(GraphPropertyEnum.TOSCA_RESOURCE_NAME);
730 if (!firstDerived.equals(firstCurrentDerived) || derivedFromGenericType) {
732 Map<GraphPropertyEnum, Object> propertiesToMatch = new HashMap<GraphPropertyEnum, Object>();
733 propertiesToMatch.put(GraphPropertyEnum.STATE, LifecycleStateEnum.CERTIFIED.name());
735 propertiesToMatch.put(GraphPropertyEnum.TOSCA_RESOURCE_NAME, firstDerived);
736 propertiesToMatch.put(GraphPropertyEnum.IS_HIGHEST_VERSION, true);
738 Either<List<GraphVertex>, TitanOperationStatus> getParentResources = titanDao.getByCriteria(VertexTypeEnum.NODE_TYPE, propertiesToMatch, JsonParseFlagEnum.NoParse);
740 if (getParentResources.isRight()) {
741 TitanOperationStatus error = getParentResources.right().value();
742 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to fetch derived by criteria {}. error {} ", propertiesToMatch, error);
743 return DaoStatusConverter.convertTitanStatusToStorageStatus(error);
746 GraphVertex newDerived = getParentResources.left().value().get(0);
747 derivedResources.add(newDerived);
748 StorageOperationStatus updateStatus = updateDataFromNewDerived(derivedResources, nodeTypeV, (NodeType)toscaElementToUpdate);
749 if (updateStatus != StorageOperationStatus.OK) {
750 CommonUtility.addRecordToLog(log, LogLevelEnum.DEBUG, "Failed to update data for {} from new derived {} ", nodeTypeV.getUniqueId(), newDerived.getUniqueId(), updateStatus);
754 Either<Edge, TitanOperationStatus> deleteEdge = titanDao.deleteEdge(nodeTypeV, firstDerivedInChain, EdgeLabelEnum.DERIVED_FROM);
755 if (deleteEdge.isRight()) {
756 TitanOperationStatus deleteError = deleteEdge.right().value();
757 log.debug("Failed to disassociate element {} from derived {} , error {}", nodeTypeV.getUniqueId(), firstDerivedInChain.getUniqueId(), deleteError);
758 return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteError);
761 titanDao.createEdge(nodeTypeV, newDerived, EdgeLabelEnum.DERIVED_FROM, new HashMap<>());
765 return StorageOperationStatus.OK;
768 private StorageOperationStatus associateDerivedDataByType(EdgeLabelEnum edgeLabel, GraphVertex nodeTypeV, NodeType nodeToUpdate, List<GraphVertex> newDerived) {
772 return associateCapabilitiesToResource(nodeTypeV, nodeToUpdate, newDerived);
774 return associateRequirementsToResource(nodeTypeV, nodeToUpdate, newDerived);
776 return associatePropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
778 return associateAttributesToResource(nodeTypeV, nodeToUpdate, newDerived);
779 case ADDITIONAL_INFORMATION:
780 return addAdditionalInformationToResource(nodeTypeV, nodeToUpdate, newDerived);
781 case CAPABILITIES_PROPERTIES:
782 return associateCapabilitiesPropertiesToResource(nodeTypeV, nodeToUpdate, newDerived);
784 return StorageOperationStatus.OK;
789 private StorageOperationStatus updateDataFromNewDerived(List<GraphVertex> newDerived, GraphVertex nodeTypeV, NodeType nodeToUpdate) {
790 EnumSet<EdgeLabelEnum> edgeLabels = EnumSet.of(EdgeLabelEnum.CAPABILITIES, EdgeLabelEnum.REQUIREMENTS, EdgeLabelEnum.PROPERTIES, EdgeLabelEnum.ATTRIBUTES, EdgeLabelEnum.CAPABILITIES_PROPERTIES, EdgeLabelEnum.ADDITIONAL_INFORMATION);
791 StorageOperationStatus status = null;
792 for (EdgeLabelEnum edge : edgeLabels){
793 status = updateDataByType(newDerived, nodeTypeV, edge, nodeToUpdate);
794 if (status != StorageOperationStatus.OK) {
802 private <T extends ToscaDataDefinition> StorageOperationStatus updateDataByType(List<GraphVertex> newDerivedList, GraphVertex nodeTypeV, EdgeLabelEnum label, NodeType nodeElement) {
803 log.debug("Update data from derived for element {} type {}", nodeTypeV.getUniqueId(), label);
804 Either<GraphVertex, TitanOperationStatus> dataFromGraph = getDataVertex(nodeTypeV, label);
805 if (dataFromGraph.isRight()) {
806 if (TitanOperationStatus.NOT_FOUND == dataFromGraph.right().value())
807 return associateDerivedDataByType(label, nodeTypeV, nodeElement, newDerivedList);
808 return DaoStatusConverter.convertTitanStatusToStorageStatus(dataFromGraph.right().value());
810 GraphVertex dataV = dataFromGraph.left().value();
812 Map<String, T> mapFromGraph = (Map<String, T>) dataV.getJson();
813 mapFromGraph.entrySet().removeIf(e -> e.getValue().getOwnerId() != null);
816 Either<Map<String, T>, StorageOperationStatus> dataFromDerived = getDataFromDerived(newDerivedList, label);
817 if (dataFromDerived.isRight()) {
818 return dataFromDerived.right().value();
820 Map<String, T> dataFromDerivedAll = dataFromDerived.left().value();
822 Either<Map<String, T>, String> merged = ToscaDataDefinition.mergeDataMaps(dataFromDerivedAll, mapFromGraph);
823 if(merged.isRight()){
824 log.debug("property {} cannot be overriden", merged.right().value());
825 return StorageOperationStatus.INVALID_PROPERTY;
827 dataV.setJson(dataFromDerivedAll);
828 Either<GraphVertex, TitanOperationStatus> updateDataV = updateOrCopyOnUpdate(dataV, nodeTypeV, label);
829 if (updateDataV.isRight()) {
830 return DaoStatusConverter.convertTitanStatusToStorageStatus(updateDataV.right().value());
832 return StorageOperationStatus.OK;
836 public <T extends ToscaElement> void fillToscaElementVertexData(GraphVertex elementV, T toscaElementToUpdate, JsonParseFlagEnum flag) {
837 fillMetadata(elementV, (NodeType) toscaElementToUpdate);