From 82e531a1ee8ffa30e80b27d9097a2272ae18cdee Mon Sep 17 00:00:00 2001 From: Mojahidul Islam Date: Tue, 14 May 2019 12:49:31 +0530 Subject: Support Capability Properties This change includes following changes 1. Get capability properties from global types- BE 2. Show capability properties in cap/req screen 3. Support Capability Properties in assingment, operation and consumption screens Change-Id: Ieb4fa5705007c8bed3d82eb4fe4604572aa202d7 Issue-ID: SDC-2294 Signed-off-by: Mojahidul Islam --- .../sdc/be/model/ComponentParametersView.java | 4 +- .../model/jsontitan/operations/BaseOperation.java | 2 +- .../operations/CapabilitiesOperation.java | 104 +++++++++++++---- .../operations/TopologyTemplateOperation.java | 55 +++++++-- .../jsontitan/operations/ToscaOperationFacade.java | 128 ++++++++++++++++++--- .../be/model/jsontitan/utils/ModelConverter.java | 51 ++++++-- .../operations/CapabilitiesOperationTest.java | 87 ++++++++++++++ .../model/jsontitan/utils/CapabilityTestUtils.java | 85 ++++++++++++++ .../model/jsontitan/utils/ModelConverterTest.java | 19 +++ 9 files changed, 483 insertions(+), 52 deletions(-) create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java (limited to 'catalog-model') diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java index 3edb8ded6c..4e7903a890 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java @@ -46,7 +46,7 @@ public class ComponentParametersView { private boolean ignoreComponentInstancesAttributesFrom = false; private boolean ignoreInputs = false; private boolean ignoreComponentInstancesInputs = false; - private boolean ignoreCapabiltyProperties = true; + private boolean ignoreCapabiltyProperties = false; private boolean ignoreServicePath = true; private boolean ignorePolicies = false; private boolean ignoreNodeFilterRequirements = false; @@ -95,6 +95,7 @@ public class ComponentParametersView { this.setIgnoreCapabilities(false); this.setIgnoreRequirements(false); this.setIgnoreNodeFilter(false); + this.setIgnoreCapabiltyProperties(false); break; case COMPONENT_INSTANCES_PROPERTIES: this.setIgnoreComponentInstances(false); //we need this in order to get the calculate capabilities requirements @@ -103,6 +104,7 @@ public class ComponentParametersView { case CAPABILITIES: this.setIgnoreComponentInstances(false);//we need this in order to get the calculate capabilities requirements this.setIgnoreCapabilities(false); + this.setIgnoreCapabiltyProperties(false); break; case REQUIREMENTS: this.setIgnoreComponentInstances(false); diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java index 6dfd1fcffb..d44865c399 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/BaseOperation.java @@ -1485,7 +1485,7 @@ public abstract class BaseOperation { return titanOperationStatus; } - private GraphVertex throwStorageException(TitanOperationStatus status) { + protected GraphVertex throwStorageException(TitanOperationStatus status) { throw new StorageException(status); } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java index a8337b6c4f..9d7f64c24a 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperation.java @@ -17,13 +17,23 @@ package org.openecomp.sdc.be.model.jsontitan.operations; import fj.data.Either; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; import org.openecomp.sdc.be.dao.jsongraph.types.EdgeLabelEnum; +import org.openecomp.sdc.be.dao.jsongraph.types.JsonParseFlagEnum; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.enums.JsonPresentationFields; +import org.openecomp.sdc.be.datatypes.tosca.ToscaDataDefinition; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate; +import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElement; +import org.openecomp.sdc.be.model.operations.StorageException; import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,20 +41,19 @@ import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; @org.springframework.stereotype.Component("capabilities-operation") public class CapabilitiesOperation extends BaseOperation { private static final Logger LOGGER = LoggerFactory.getLogger(CapabilitiesOperation.class); - public Either, StorageOperationStatus> addCapabilities( - String componentId, - List capabilityDefinitions) { + public Either, StorageOperationStatus> addCapabilities(String componentId, + List capabilityDefinitions) { return addOrUpdateCapabilities(componentId, capabilityDefinitions, false); } - public Either, StorageOperationStatus> updateCapabilities( - String componentId, - List capabilityDefinitions) { + public Either, StorageOperationStatus> updateCapabilities(String componentId, + List capabilityDefinitions) { return addOrUpdateCapabilities(componentId, capabilityDefinitions, true); } @@ -52,33 +61,31 @@ public class CapabilitiesOperation extends BaseOperation { List capabilityDefinitions, boolean isUpdateAction) { StorageOperationStatus statusRes = performUpdateToscaAction(isUpdateAction, - componentId, Collections - .singletonList(convertToListCapabilityDataDefinition(capabilityDefinitions))); + componentId, Collections.singletonList(convertToListCapabilityDataDefinition(capabilityDefinitions))); if (!statusRes.equals(StorageOperationStatus.OK)) { - titanDao.rollback(); - LOGGER.error("Failed to find the parent capability of capability type {}." - + " status is {}", componentId, statusRes); + LOGGER.error("Failed to find the parent capability of capability type {}." + " status is {}", componentId, + statusRes); return Either.right(statusRes); } - titanDao.commit(); return Either.left(capabilityDefinitions); } - public StorageOperationStatus deleteCapabilities(Component component, - String capabilityIdToDelete) { - return deleteToscaDataElements(component.getUniqueId(), - EdgeLabelEnum.CAPABILITIES, + public StorageOperationStatus deleteCapabilities(Component component, String capabilityIdToDelete) { + return deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.CAPABILITIES, Collections.singletonList(capabilityIdToDelete)); } - private static ListCapabilityDataDefinition convertToListCapabilityDataDefinition( - List capabilities) { + public StorageOperationStatus deleteCapabilityProperties(Component component, String capabilityPropIdToDelete) { + return deleteToscaDataElements(component.getUniqueId(), EdgeLabelEnum.CAPABILITIES_PROPERTIES, + Collections.singletonList(capabilityPropIdToDelete)); + } + + private static ListCapabilityDataDefinition convertToListCapabilityDataDefinition(List capabilities) { List capabilityDefinitions = new ArrayList<>(capabilities); return new ListCapabilityDataDefinition(capabilityDefinitions); } - private StorageOperationStatus performUpdateToscaAction(boolean isUpdate, - String componentId, + private StorageOperationStatus performUpdateToscaAction(boolean isUpdate, String componentId, List toscaDataList) { if (isUpdate) { return updateToscaDataOfToscaElement(componentId, EdgeLabelEnum.CAPABILITIES, @@ -88,4 +95,61 @@ public class CapabilitiesOperation extends BaseOperation { VertexTypeEnum.CAPABILITIES, toscaDataList, JsonPresentationFields.TYPE); } } + + private StorageOperationStatus createOrUpdateCapabilityProperties(String componentId, TopologyTemplate toscaElement, + Map propertiesMap) { + GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse) + .left().on(this::throwStorageException); + Map capabilitiesProperties = toscaElement.getCapabilitiesProperties(); + if(MapUtils.isNotEmpty(capabilitiesProperties)) { + + capabilitiesProperties.forEach((key, val) -> { + Map mapToscaDataDefinition = val.getMapToscaDataDefinition(); + mapToscaDataDefinition.forEach((key1, val1) -> { + + propertiesMap.forEach((propKey, propVal) -> { + Map propValMapToscaDataDefinition = propVal.getMapToscaDataDefinition(); + propValMapToscaDataDefinition.forEach((propKey1, propVal1) -> { + if(propKey1.equals(key1) && val1.getUniqueId().equals(propVal1.getUniqueId())) { + ToscaDataDefinition.mergeDataMaps(mapToscaDataDefinition, propValMapToscaDataDefinition); + } + }); + }); + }); + }); + + ToscaDataDefinition.mergeDataMaps(propertiesMap, capabilitiesProperties); + } + + return topologyTemplateOperation.updateFullToscaData(toscaElementV, + EdgeLabelEnum.CAPABILITIES_PROPERTIES, VertexTypeEnum.CAPABILITIES_PROPERTIES, propertiesMap); + } + + public StorageOperationStatus createOrUpdateCapabilityProperties(String componentId, + Map propertiesMap) { + StorageOperationStatus propertiesStatusRes = null; + if(MapUtils.isNotEmpty(propertiesMap)) { + propertiesStatusRes = createOrUpdateCapabilityProperties(componentId, getTopologyTemplate(componentId), + propertiesMap); + } + + return propertiesStatusRes; + } + + private TopologyTemplate getTopologyTemplate(String componentId) { + return (TopologyTemplate)topologyTemplateOperation + .getToscaElement(componentId, getFilterComponentWithCapProperties()) + .left() + .on(this::throwStorageException); + } + private ComponentParametersView getFilterComponentWithCapProperties() { + ComponentParametersView filter = new ComponentParametersView(); + filter.setIgnoreCapabiltyProperties(false); + return filter; + } + + private ToscaElement throwStorageException(StorageOperationStatus status) { + throw new StorageException(status); + } + } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java index b0bfc153f4..5ddc5287ed 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/TopologyTemplateOperation.java @@ -253,11 +253,24 @@ public class TopologyTemplateOperation extends ToscaElementOperation { } private StorageOperationStatus associateCapPropertiesToResource(GraphVertex topologyTemplateVertex, TopologyTemplate topologyTemplate) { - Map calculatedCapProperties = topologyTemplate.getCalculatedCapabilitiesProperties(); - if (calculatedCapProperties != null && !calculatedCapProperties.isEmpty()) { - Either assosiateElementToData = associateElementToData(topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties); - if (assosiateElementToData.isRight()) { - return assosiateElementToData.right().value(); + Map calculatedCapProperties = topologyTemplate + .getCalculatedCapabilitiesProperties(); + if (MapUtils.isNotEmpty(calculatedCapProperties)) { + Either associateElementToData = associateElementToData + (topologyTemplateVertex, VertexTypeEnum.CALCULATED_CAP_PROPERTIES, + EdgeLabelEnum.CALCULATED_CAP_PROPERTIES, calculatedCapProperties); + if (associateElementToData.isRight()) { + return associateElementToData.right().value(); + } + } + + Map capabilitiesProperties = topologyTemplate.getCapabilitiesProperties(); + if (MapUtils.isNotEmpty(capabilitiesProperties)) { + Either associateElementToData = + associateElementToData(topologyTemplateVertex, VertexTypeEnum.CAPABILITIES_PROPERTIES, + EdgeLabelEnum.CAPABILITIES_PROPERTIES, capabilitiesProperties); + if (associateElementToData.isRight()) { + return associateElementToData.right().value(); } } return StorageOperationStatus.OK; @@ -888,6 +901,16 @@ public class TopologyTemplateOperation extends ToscaElementOperation { return result.right().value(); } } + Either, TitanOperationStatus> capPropResult = + getDataFromGraph(componentV, EdgeLabelEnum.CAPABILITIES_PROPERTIES); + if (capPropResult.isLeft()) { + topologyTemplate.setCapabilitiesProperties(capPropResult.left().value()); + } else { + if (capPropResult.right().value() != TitanOperationStatus.NOT_FOUND) { + return capPropResult.right().value(); + } + } + return TitanOperationStatus.OK; } @@ -1173,6 +1196,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation { log.debug("Failed to disassociate instance inputs for {} error {}", toscaElementVertex.getUniqueId(), status); return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); } + status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CAPABILITIES_PROPERTIES); + if (status != TitanOperationStatus.OK) { + log.debug("Failed to disassociate capabilities properties for {} error {}", toscaElementVertex.getUniqueId(), status); + Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } status = titanDao.disassociateAndDeleteLast(toscaElementVertex, Direction.OUT, EdgeLabelEnum.CALCULATED_CAPABILITIES); if (status != TitanOperationStatus.OK) { log.debug("Failed to disassociate calculated capabiliites for {} error {}", toscaElementVertex.getUniqueId(), status); @@ -1521,10 +1549,6 @@ public class TopologyTemplateOperation extends ToscaElementOperation { } } - private GraphVertex throwStorageException(TitanOperationStatus status) { - throw new StorageException(status); - } - private ToscaElement getOriginToscaElement(ComponentInstanceDataDefinition instance) { log.debug("#getOriginToscaElement - origin name: {}", instance.getComponentName()); ToscaElementTypeEnum elementType = detectToscaType(instance.getOriginType()); @@ -1558,11 +1582,12 @@ public class TopologyTemplateOperation extends ToscaElementOperation { filter.setIgnoreRequirements(false); return filter; } - public void updateCapReqOwnerId(String componentId, TopologyTemplate toscaElement) { + public void updateCapReqPropertiesOwnerId(String componentId, TopologyTemplate toscaElement) { GraphVertex toscaElementV = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse) .left().on(this::throwStorageException); updateCapOwnerId(toscaElement, componentId); updateReqOwnerId(toscaElement, componentId); + updatePropertiesOwnerId(toscaElement, componentId); topologyTemplateOperation .updateFullToscaData(toscaElementV, EdgeLabelEnum.CAPABILITIES, @@ -1570,6 +1595,9 @@ public class TopologyTemplateOperation extends ToscaElementOperation { topologyTemplateOperation .updateFullToscaData(toscaElementV, EdgeLabelEnum.REQUIREMENTS, VertexTypeEnum.REQUIREMENTS, toscaElement.getRequirements()); + topologyTemplateOperation + .updateFullToscaData(toscaElementV, EdgeLabelEnum.PROPERTIES, + VertexTypeEnum.PROPERTIES, toscaElement.getProperties()); } private void updateCapOwnerId(ToscaElement toscaElement, String ownerId) { @@ -1586,4 +1614,11 @@ public class TopologyTemplateOperation extends ToscaElementOperation { } } + private void updatePropertiesOwnerId(ToscaElement toscaElement, String ownerId) { + Map properties = toscaElement.getProperties(); + if(MapUtils.isNotEmpty(properties)) { + properties.values().forEach(propertyDataDefinition -> propertyDataDefinition.setParentUniqueId(ownerId)); + } + } + } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java index 8456486bef..4482f7f943 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/operations/ToscaOperationFacade.java @@ -1236,23 +1236,28 @@ public class ToscaOperationFacade { public Either>, StorageOperationStatus> addComponentInstancePropertiesToComponent(Component containerComponent, Map> instProperties) { requireNonNull(instProperties); - StorageOperationStatus status; + StorageOperationStatus status = null; for (Entry> entry : instProperties.entrySet()) { List props = entry.getValue(); String componentInstanceId = entry.getKey(); - List instanceProperties = containerComponent.getComponentInstancesProperties().get(componentInstanceId); + + Map> containerComponentCapabilities = containerComponent.getCapabilities(); + if (!isEmpty(props)) { for (ComponentInstanceProperty property : props) { - Optional instanceProperty = instanceProperties.stream() - .filter(p -> p.getUniqueId().equals(property.getUniqueId())) - .findAny(); - if (instanceProperty.isPresent()) { - status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property); - } else { - status = addComponentInstanceProperty(containerComponent, componentInstanceId, property); + String propertyParentUniqueId = property.getParentUniqueId(); + Optional + capPropDefinition = getPropertyCapability(propertyParentUniqueId, containerComponent); + if(capPropDefinition.isPresent() && MapUtils.isNotEmpty(containerComponentCapabilities)) { + status = populateAndUpdateInstanceCapProperty(containerComponent, componentInstanceId, + containerComponentCapabilities, property, capPropDefinition.get()); } - if (status != StorageOperationStatus.OK) { - log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status); + if(status == null) { + List instanceProperties = containerComponent + .getComponentInstancesProperties().get(componentInstanceId); + status = updateInstanceProperty(containerComponent, componentInstanceId, instanceProperties, property); + } + if(status != StorageOperationStatus.OK) { return Either.right(status); } } @@ -1261,6 +1266,103 @@ public class ToscaOperationFacade { return Either.left(instProperties); } + private StorageOperationStatus populateAndUpdateInstanceCapProperty(Component containerComponent, String componentInstanceId, + Map> containerComponentCapabilities, + ComponentInstanceProperty property, + CapabilityDefinition capabilityDefinition) { + List capabilityDefinitions = containerComponentCapabilities.get(capabilityDefinition.getType()); + if(CollectionUtils.isEmpty(capabilityDefinitions)) { + return null; + } + Optional capDefToGetProp = capabilityDefinitions.stream() + .filter(cap -> cap.getUniqueId().equals(capabilityDefinition.getUniqueId()) && cap.getPath().size() == 1).findAny(); + if(capDefToGetProp.isPresent()) { + return updateInstanceCapabilityProperty(containerComponent, componentInstanceId, property, capDefToGetProp.get()); + } + return null; + } + + private static Optional getPropertyCapability(String propertyParentUniqueId, + Component containerComponent) { + + Map> componentCapabilities = containerComponent.getCapabilities(); + if(MapUtils.isEmpty(componentCapabilities)){ + return Optional.empty(); + } + List capabilityDefinitionList = componentCapabilities.values() + .stream().flatMap(Collection::stream).collect(Collectors.toList()); + if(CollectionUtils.isEmpty(capabilityDefinitionList)){ + return Optional.empty(); + } + return capabilityDefinitionList.stream() + .filter(capabilityDefinition -> capabilityDefinition.getUniqueId().equals(propertyParentUniqueId)) + .findAny(); + } + + private StorageOperationStatus updateInstanceProperty(Component containerComponent, String componentInstanceId, + List instanceProperties, + ComponentInstanceProperty property) { + StorageOperationStatus status; + Optional instanceProperty = instanceProperties.stream() + .filter(p -> p.getUniqueId().equals(property.getUniqueId())) + .findAny(); + if (instanceProperty.isPresent()) { + status = updateComponentInstanceProperty(containerComponent, componentInstanceId, property); + } else { + status = addComponentInstanceProperty(containerComponent, componentInstanceId, property); + } + if (status != StorageOperationStatus.OK) { + log.debug("Failed to update instance property {} for instance {} error {} ", property, componentInstanceId, status); + return status; + } + return StorageOperationStatus.OK; + } + + public StorageOperationStatus updateInstanceCapabilityProperty(Component containerComponent, String componentInstanceId, + ComponentInstanceProperty property, + CapabilityDefinition capabilityDefinition) { + Optional fetchedCIOptional = containerComponent.getComponentInstanceById(componentInstanceId); + if(!fetchedCIOptional.isPresent()) { + return StorageOperationStatus.GENERAL_ERROR; + } + Either getComponentRes = + getToscaFullElement(fetchedCIOptional.get().getComponentUid()); + if(getComponentRes.isRight()) { + return StorageOperationStatus.GENERAL_ERROR; + } + Optional componentOptional = isNodeServiceProxy(getComponentRes.left().value()); + String propOwner; + if(!componentOptional.isPresent()) { + propOwner = componentInstanceId; + } else { + propOwner = fetchedCIOptional.get().getSourceModelUid(); + } + StorageOperationStatus status; + StringBuffer sb = new StringBuffer(componentInstanceId); + sb.append(ModelConverter.CAP_PROP_DELIM).append(propOwner).append(ModelConverter.CAP_PROP_DELIM) + .append(capabilityDefinition.getType()).append(ModelConverter.CAP_PROP_DELIM).append(capabilityDefinition.getName()); + String capKey = sb.toString(); + status = updateComponentInstanceCapabiltyProperty(containerComponent, componentInstanceId, capKey, property); + if (status != StorageOperationStatus.OK) { + log.debug("Failed to update instance capability property {} for instance {} error {} ", property, + componentInstanceId, status); + return status; + } + return StorageOperationStatus.OK; + } + + private Optional isNodeServiceProxy(Component component) { + if (component.getComponentType().equals(ComponentTypeEnum.SERVICE)) { + return Optional.empty(); + } + Resource resource = (Resource) component; + ResourceTypeEnum resType = resource.getResourceType(); + if(resType.equals(ResourceTypeEnum.ServiceProxy)) { + return Optional.of(component); + } + return Optional.empty(); + } + public StorageOperationStatus associateDeploymentArtifactsToInstances(Map> instDeploymentArtifacts, String componentId, User user) { Either getVertexEither = titanDao.getVertexById(componentId, JsonParseFlagEnum.NoParse); @@ -2634,8 +2736,8 @@ public class ToscaOperationFacade { } return Either.left(parentComponents); } - public void updateCapReqOwnerId(String componentId) { + public void updateCapReqPropertiesOwnerId(String componentId) { topologyTemplateOperation - .updateCapReqOwnerId(componentId, getTopologyTemplate(componentId)); + .updateCapReqPropertiesOwnerId(componentId, getTopologyTemplate(componentId)); } } diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java index cfd00a5313..9412c5c70b 100644 --- a/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverter.java @@ -464,7 +464,9 @@ public class ModelConverter { if (CollectionUtils.isNotEmpty(capPrps)) { MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition(); for (ComponentInstanceProperty cip : capPrps) { - dataToCreate.put(cip.getName(), new PropertyDataDefinition(cip)); + PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(cip); + propertyDataDefinition.setParentUniqueId(cap.getUniqueId()); + dataToCreate.put(cip.getName(), propertyDataDefinition); } toscaCapPropMap.put(s + CAP_PROP_DELIM + cap.getName(), dataToCreate); } @@ -1384,16 +1386,51 @@ public class ModelConverter { private static void setCapabilitiesToComponent(TopologyTemplate topologyTemplate, Component component) { Map capabilities = topologyTemplate.getCapabilities(); - Map> componentCapabilities = component.getCapabilities(); + Map capabilitiesProperties = topologyTemplate.getCapabilitiesProperties(); + Map> allCapabilities = new HashMap<>(); + if(MapUtils.isNotEmpty(capabilities)) { - if(componentCapabilities == null) { - componentCapabilities = new HashMap<>(); - } - componentCapabilities.putAll(groupCapabilityByType(capabilities)); - component.setCapabilities(componentCapabilities); + allCapabilities.putAll(groupCapabilityByType(capabilities)); + } + + if(MapUtils.isNotEmpty(capabilitiesProperties)) { + capabilitiesProperties.forEach((s, capProp)-> { + String[] result = s.split(CAP_PROP_DELIM); + if (capProp != null) { + Map capMap = capProp.getMapToscaDataDefinition(); + + if (MapUtils.isNotEmpty(capMap)) { + List capPropsList = capMap.values().stream() + .map(ComponentInstanceProperty::new).collect(Collectors.toList()); + + List cap = allCapabilities.get(result[0]); + if (cap !=null) { + Optional op = cap.stream().filter(c -> c.getName() + .equals(result[1])).findFirst(); + op.ifPresent(capabilityDefinition -> capabilityDefinition.setProperties(capPropsList)); + } + } + } + } + ); + } + Map> componentCapabilities = component.getCapabilities(); + if(MapUtils.isNotEmpty(componentCapabilities)) { + mergeCapabilityMap(allCapabilities, componentCapabilities); } + component.setCapabilities(allCapabilities); + } + private static void mergeCapabilityMap(Map> map1, + Map> map2) { + map1.forEach((key1, val1) -> map2.forEach((key2, val2) -> { + if(key1.equals(key2)) { + val2.addAll(val1); + } + })); + map1.putAll(map2); } + private static Map> groupCapabilityByType(Map capabilities) { Map> groupedCapabilities = new HashMap<>(); diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java new file mode 100644 index 0000000000..0c9c35b62a --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/operations/CapabilitiesOperationTest.java @@ -0,0 +1,87 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.model.jsontitan.operations; + +import fj.data.Either; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.openecomp.sdc.be.dao.jsongraph.GraphVertex; +import org.openecomp.sdc.be.dao.jsongraph.TitanDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate; +import org.openecomp.sdc.be.model.jsontitan.utils.CapabilityTestUtils; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +import java.util.HashMap; +import java.util.Map; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyMap; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.when; + +public class CapabilitiesOperationTest { + + @InjectMocks + CapabilitiesOperation operation = new CapabilitiesOperation(); + @Mock + private TitanDao mockTitanDao; + @Mock + private TopologyTemplateOperation topologyTemplateOperation; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + when(mockTitanDao.commit()).thenReturn(TitanOperationStatus.OK); + when(mockTitanDao.getVertexById(anyString(), any())).thenReturn(Either.left(new GraphVertex())); + + when(topologyTemplateOperation.updateFullToscaData(any(), any(), any(), anyMap())).thenReturn(StorageOperationStatus.OK); + TopologyTemplate topologyTemplate = new TopologyTemplate(); + + Map capPropsForTopologyTemplate = CapabilityTestUtils + .createCapPropsForTopologyTemplate(topologyTemplate); + topologyTemplate.setCapabilitiesProperties(capPropsForTopologyTemplate); + + when(topologyTemplateOperation.getToscaElement(anyString(), any())).thenReturn(Either.left(topologyTemplate)); + } + + @Test + public void testCreateOrUpdateCapabilitiesProperties() { + + Map mapToscaDataDefinition = new HashMap<>(); + PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(); + propertyDataDefinition.setUniqueId("ComponentInput1_uniqueId"); + propertyDataDefinition.setName("propName"); + mapToscaDataDefinition.put(propertyDataDefinition.getUniqueId(), propertyDataDefinition); + MapPropertiesDataDefinition mapPropertiesDataDefinition = new MapPropertiesDataDefinition(mapToscaDataDefinition); + + Map propertiesMap = new HashMap<>(); + propertiesMap.put(propertyDataDefinition.getUniqueId(), mapPropertiesDataDefinition); + + StorageOperationStatus operationStatus = operation.createOrUpdateCapabilityProperties("componentId", + propertiesMap); + + Assert.assertEquals(StorageOperationStatus.OK, operationStatus); + } +} \ No newline at end of file diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java new file mode 100644 index 0000000000..6f6b7eacad --- /dev/null +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/CapabilityTestUtils.java @@ -0,0 +1,85 @@ +/* + * Copyright © 2016-2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.be.model.jsontitan.utils; + +import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class CapabilityTestUtils { + + public static Map createCapPropsForTopologyTemplate(TopologyTemplate topologyTemplate) { + Map capabilitiesMap = new HashMap<>(); + + List capabilityDefinitions = new ArrayList<>(); + CapabilityDefinition capabilityDefinition = createCapabilityDefinition(); + + capabilityDefinitions.add(capabilityDefinition); + ListCapabilityDataDefinition listCapabilityDataDefinition = new ListCapabilityDataDefinition(capabilityDefinitions); + capabilitiesMap.put(capabilityDefinition.getType(), listCapabilityDataDefinition); + topologyTemplate.setCapabilities(capabilitiesMap); + + List capPropList = new ArrayList<>(); + ComponentInstanceProperty instanceProperty = createProperties(); + capPropList.add(instanceProperty); + + MapPropertiesDataDefinition dataToCreate = new MapPropertiesDataDefinition(); + for (ComponentInstanceProperty cip : capPropList) { + PropertyDataDefinition propertyDataDefinition = new PropertyDataDefinition(cip); + dataToCreate.put(cip.getName(), propertyDataDefinition); + } + + Map capabilitiesProperties = new HashMap<>(); + capabilitiesProperties.put(capabilityDefinition.getType() + ModelConverter.CAP_PROP_DELIM + + capabilityDefinition.getName(), dataToCreate); + return capabilitiesProperties; + } + + private static CapabilityDefinition createCapabilityDefinition() { + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setName("cap" + Math.random()); + capabilityDefinition.setType("tosca.capabilities.network.Bindable"); + capabilityDefinition.setOwnerId("resourceId"); + capabilityDefinition.setUniqueId("capUniqueId"); + List path = new ArrayList<>(); + path.add("path1"); + capabilityDefinition.setPath(path); + return capabilityDefinition; + } + + private static ComponentInstanceProperty createProperties() { + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(); + instanceProperty.setUniqueId("ComponentInput1_uniqueId"); + instanceProperty.setType("Integer"); + instanceProperty.setName("prop_name"); + instanceProperty.setDescription("prop_description_prop_desc"); + instanceProperty.setOwnerId("capUniqueId"); + instanceProperty.setValue("{\"get_input\":\"extcp20_order\"}"); + instanceProperty.setSchema(new SchemaDefinition()); + return instanceProperty; + } +} diff --git a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverterTest.java b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverterTest.java index f8713c6b78..a927f5a461 100644 --- a/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverterTest.java +++ b/catalog-model/src/test/java/org/openecomp/sdc/be/model/jsontitan/utils/ModelConverterTest.java @@ -34,6 +34,7 @@ import org.junit.runner.RunWith; import org.mockito.InjectMocks; import org.mockito.junit.MockitoJUnitRunner; import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum; +import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition; import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; import org.openecomp.sdc.be.model.Resource; @@ -42,6 +43,9 @@ import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.jsontitan.datamodel.TopologyTemplate; import org.openecomp.sdc.be.model.jsontitan.datamodel.NodeType; import org.openecomp.sdc.be.model.jsontitan.datamodel.ToscaElementTypeEnum; + +import java.util.Map; + import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; @@ -78,6 +82,21 @@ public class ModelConverterTest { assertThat(component.getToscaType()).isEqualTo(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue()); } + @Test + public void testConvertFromToscaElementServiceWithSelfCapabilities() + { + TopologyTemplate topologyTemplate = new TopologyTemplate(); + + Map capabilitiesProperties = CapabilityTestUtils + .createCapPropsForTopologyTemplate(topologyTemplate); + + topologyTemplate.setCapabilitiesProperties(capabilitiesProperties); + + topologyTemplate.setComponentType(ComponentTypeEnum.SERVICE); + Component component = test.convertFromToscaElement(topologyTemplate); + assertThat(component.getToscaType()).isEqualTo(ToscaElementTypeEnum.TOPOLOGY_TEMPLATE.getValue()); + } + @Test public void testConvertFromToscaElementResource() { -- cgit 1.2.3-korg