From ebffd13f0100839fecf5dbcd5c83856c193d8109 Mon Sep 17 00:00:00 2001 From: franciscovila Date: Tue, 26 Jul 2022 14:49:32 +0100 Subject: Service Import - Node Template Interface Definitions Add Node Template Interface Definitions when importing a service Issue-ID: SDC-4113 Signed-off-by: franciscovila Change-Id: I28bcb120ebd25b0baa4e62404d3fe38ce3a3706f --- .../csar/YamlTemplateParsingHandler.java | 228 +++++++++++++++++++-- .../impl/InterfaceDefinitionHandler.java | 6 + .../impl/ServiceImportBusinessLogic.java | 122 ++++++++++- .../components/impl/ServiceImportParseLogic.java | 59 ++++-- .../csar/YamlTemplateParsingHandlerTest.java | 38 ++-- .../impl/InterfaceDefinitionHandlerTest.java | 2 +- .../impl/ServiceImportBusinessLogicTest.java | 8 +- 7 files changed, 406 insertions(+), 57 deletions(-) (limited to 'catalog-be/src') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java index cbba46f35c..ee31112253 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java @@ -23,6 +23,7 @@ package org.openecomp.sdc.be.components.csar; import static java.util.stream.Collectors.toList; +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.QUOTE; import static org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import static org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaListElement; @@ -62,21 +63,25 @@ import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TE import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE; import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.VALID_SOURCE_TYPES; +import com.att.aft.dme2.internal.gson.reflect.TypeToken; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.gson.Gson; import fj.data.Either; +import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Objects; import java.util.Optional; import java.util.Set; +import java.util.UUID; import java.util.stream.Collectors; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; @@ -90,9 +95,12 @@ import org.openecomp.sdc.be.components.impl.exceptions.ByActionStatusComponentEx import org.openecomp.sdc.be.config.BeEcompErrorManager; import org.openecomp.sdc.be.dao.api.ActionStatus; import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyTargetType; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; @@ -112,10 +120,12 @@ import org.openecomp.sdc.be.model.UploadArtifactInfo; import org.openecomp.sdc.be.model.UploadAttributeInfo; import org.openecomp.sdc.be.model.UploadCapInfo; import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; +import org.openecomp.sdc.be.model.UploadInterfaceInfo; import org.openecomp.sdc.be.model.UploadPropInfo; import org.openecomp.sdc.be.model.UploadReqInfo; import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; import org.openecomp.sdc.be.tosca.model.ToscaInterfaceDefinition; +import org.openecomp.sdc.be.tosca.utils.OperationArtifactUtil; import org.openecomp.sdc.be.ui.model.OperationUi; import org.openecomp.sdc.be.ui.model.PropertyAssignmentUi; import org.openecomp.sdc.be.utils.TypeUtils; @@ -131,6 +141,7 @@ public class YamlTemplateParsingHandler { private static final int SUB_MAPPING_CAPABILITY_OWNER_NAME_IDX = 0; private static final int SUB_MAPPING_CAPABILITY_NAME_IDX = 1; private static final Logger log = Logger.getLogger(YamlTemplateParsingHandler.class); + private static final String WITH_ATTRIBUTE = "with attribute '{}': '{}'"; private final Gson gson = new Gson(); private final JanusGraphDao janusGraphDao; private final GroupTypeBusinessLogic groupTypeBusinessLogic; @@ -138,9 +149,12 @@ public class YamlTemplateParsingHandler { private final PolicyTypeBusinessLogic policyTypeBusinessLogic; private final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler; - public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao, GroupTypeBusinessLogic groupTypeBusinessLogic, - AnnotationBusinessLogic annotationBusinessLogic, PolicyTypeBusinessLogic policyTypeBusinessLogic, - final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler) { + public YamlTemplateParsingHandler(JanusGraphDao janusGraphDao, + GroupTypeBusinessLogic groupTypeBusinessLogic, + AnnotationBusinessLogic annotationBusinessLogic, + PolicyTypeBusinessLogic policyTypeBusinessLogic, + final ToscaFunctionYamlParsingHandler toscaFunctionYamlParsingHandler + ) { this.janusGraphDao = janusGraphDao; this.groupTypeBusinessLogic = groupTypeBusinessLogic; this.annotationBusinessLogic = annotationBusinessLogic; @@ -162,7 +176,10 @@ public class YamlTemplateParsingHandler { .filter(entry -> entry.getKey().equals(OUTPUTS.getElementName())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); parsedToscaYamlInfo.setInputs(getInputs(mappedTopologyTemplateInputs)); parsedToscaYamlInfo.setOutputs(getOutputs(mappedTopologyTemplateOutputs)); - parsedToscaYamlInfo.setInstances(getInstances(mappedToscaTemplate, createdNodesToscaResourceNames)); + parsedToscaYamlInfo.setInstances(getInstances( + mappedToscaTemplate, + createdNodesToscaResourceNames + )); associateRelationshipTemplatesToInstances(parsedToscaYamlInfo.getInstances(), mappedTopologyTemplate); parsedToscaYamlInfo.setGroups(getGroups(mappedToscaTemplate, component.getModel())); parsedToscaYamlInfo.setPolicies(getPolicies(mappedToscaTemplate, component.getModel())); @@ -347,20 +364,34 @@ public class YamlTemplateParsingHandler { return targets; } - private Map getInstances(Map toscaJson, - Map createdNodesToscaResourceNames) { - Map nodeTemplates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES).left().on(err -> new HashMap<>()); + private Map getInstances( + Map toscaJson, + Map createdNodesToscaResourceNames + ) { + Map nodeTemplates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES) + .left().on(err -> new HashMap<>()); if (nodeTemplates.isEmpty()) { return Collections.emptyMap(); } - return getInstances(toscaJson, createdNodesToscaResourceNames, nodeTemplates); + return getInstances( + toscaJson, + createdNodesToscaResourceNames, + nodeTemplates + ); } - private Map getInstances(Map toscaJson, Map createdNodesToscaResourceNames, - Map nodeTemplates) { + private Map getInstances( + Map toscaJson, + Map createdNodesToscaResourceNames, + Map nodeTemplates + ) { Map substitutionMappings = getSubstitutionMappings(toscaJson); return nodeTemplates.entrySet().stream() - .map(node -> buildModuleComponentInstanceInfo(node, substitutionMappings, createdNodesToscaResourceNames)) + .map(node -> buildModuleComponentInstanceInfo( + node, + substitutionMappings, + createdNodesToscaResourceNames + )) .collect(Collectors.toMap(UploadComponentInstanceInfo::getName, i -> i)); } @@ -739,9 +770,11 @@ public class YamlTemplateParsingHandler { } @SuppressWarnings("unchecked") - private UploadComponentInstanceInfo buildModuleComponentInstanceInfo(Map.Entry nodeTemplateJsonEntry, - Map substitutionMappings, - Map createdNodesToscaResourceNames) { + private UploadComponentInstanceInfo buildModuleComponentInstanceInfo( + Map.Entry nodeTemplateJsonEntry, + Map substitutionMappings, + Map createdNodesToscaResourceNames + ) { UploadComponentInstanceInfo nodeTemplateInfo = new UploadComponentInstanceInfo(); nodeTemplateInfo.setName(nodeTemplateJsonEntry.getKey()); try { @@ -756,6 +789,7 @@ public class YamlTemplateParsingHandler { setArtifacts(nodeTemplateInfo, nodeTemplateJsonMap); updateProperties(nodeTemplateInfo, nodeTemplateJsonMap); updateAttributes(nodeTemplateInfo, nodeTemplateJsonMap); + updateInterfaces(nodeTemplateInfo, nodeTemplateJsonMap); setDirectives(nodeTemplateInfo, nodeTemplateJsonMap); setNodeFilter(nodeTemplateInfo, nodeTemplateJsonMap); setSubstitutions(substitutionMappings, nodeTemplateInfo); @@ -803,6 +837,20 @@ public class YamlTemplateParsingHandler { } } + private void updateInterfaces( + UploadComponentInstanceInfo nodeTemplateInfo, + Map nodeTemplateJsonMap + ){ + if (nodeTemplateJsonMap.containsKey(INTERFACES.getElementName())) { + Map interfaces = buildInterfacesModuleFromYaml( + nodeTemplateJsonMap + ); + if (!interfaces.isEmpty()) { + nodeTemplateInfo.setInterfaces(interfaces); + } + } + } + private void setCapabilities(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { if (nodeTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) { Map> eitherCapRes = createCapModuleFromYaml(nodeTemplateJsonMap); @@ -1044,7 +1092,8 @@ public class YamlTemplateParsingHandler { return regTemplateInfo; } - private Map buildAttributeModuleFromYaml(Map nodeTemplateJsonMap) { + private Map buildAttributeModuleFromYaml( + Map nodeTemplateJsonMap) { Map moduleAttribute = new HashMap<>(); Either, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(nodeTemplateJsonMap, ATTRIBUTES); if (toscaAttributes.isLeft()) { @@ -1070,6 +1119,20 @@ public class YamlTemplateParsingHandler { return moduleProp; } + private Map buildInterfacesModuleFromYaml( + Map nodeTemplateJsonMap + ) { + Map moduleInterfaces = new HashMap<>(); + Either, ResultStatusEnum> toscaInterfaces = findFirstToscaMapElement(nodeTemplateJsonMap, INTERFACES); + if (toscaInterfaces.isLeft()) { + Map jsonInterfaces = toscaInterfaces.left().value(); + for (Map.Entry jsonInterfacesObj : jsonInterfaces.entrySet()) { + addInterfaces(moduleInterfaces, jsonInterfacesObj); + } + } + return moduleInterfaces; + } + private void addProperty(Map> moduleProp, Map.Entry jsonPropObj) { UploadPropInfo propertyDef = buildProperty(jsonPropObj.getKey(), jsonPropObj.getValue()); if (moduleProp.containsKey(propertyDef.getName())) { @@ -1081,6 +1144,11 @@ public class YamlTemplateParsingHandler { } } + private void addInterfaces(Map moduleInterface, Map.Entry jsonPropObj) { + UploadInterfaceInfo interfaceInfo = buildInterface(jsonPropObj.getKey(), jsonPropObj.getValue()); + moduleInterface.put(jsonPropObj.getKey(), interfaceInfo); + } + @SuppressWarnings("unchecked") private UploadPropInfo buildProperty(String propName, Object propValueObj) { final var propertyDef = new UploadPropInfo(); @@ -1115,6 +1183,136 @@ public class YamlTemplateParsingHandler { return propertyDef; } + private UploadInterfaceInfo buildInterface(String interfaceName, Object interfaceValue) { + UploadInterfaceInfo interfaceDef = new UploadInterfaceInfo(); + interfaceDef.setValue(interfaceValue); + interfaceDef.setName(interfaceName); + interfaceDef.setKey(interfaceName); + Map operations = new HashMap<>(); + if (interfaceValue instanceof Map) { + Map operationsMap = (Map) interfaceValue; + for (Map.Entry operationEntry : operationsMap.entrySet()) { + OperationDataDefinition operationDef = new OperationDataDefinition(); + operationDef.setName(operationEntry.getKey()); + Map operationValue = (Map) operationEntry.getValue(); + if (operationValue.containsKey(DESCRIPTION.getElementName())) { + operationDef.setDescription(operationValue.get(DESCRIPTION.getElementName()).toString()); + } + operationDef.setImplementation(handleOperationImplementation(operationValue).orElse(new ArtifactDataDefinition())); + if (operationValue.containsKey(INPUTS.getElementName())) { + final Map interfaceInputs = (Map) operationValue.get(INPUTS.getElementName()); + operationDef.setInputs(handleInterfaceOperationInputs(interfaceInputs)); + } + operations.put(operationEntry.getKey(), operationDef); + } + interfaceDef.setOperations(operations); + if (operationsMap.containsKey(TYPE.getElementName())) { + interfaceDef.setType(((Map) interfaceValue).get(TYPE.getElementName()).toString()); + } + } + return interfaceDef; + } + + private ListDataDefinition handleInterfaceOperationInputs(final Map interfaceInputs) { + final ListDataDefinition inputs = new ListDataDefinition<>(); + for (final Entry interfaceInput : interfaceInputs.entrySet()) { + final OperationInputDefinition operationInput = new OperationInputDefinition(); + operationInput.setUniqueId(UUID.randomUUID().toString()); + operationInput.setInputId(operationInput.getUniqueId()); + operationInput.setName(interfaceInput.getKey()); + handleInputToscaDefinition(interfaceInput.getKey(), interfaceInput.getValue(), operationInput); + inputs.add(operationInput); + } + return inputs; + } + + private void handleInputToscaDefinition( + final String inputName, + final Object value, + final OperationInputDefinition operationInput + ) { + if (value instanceof Map) { + log.debug("Creating interface operation input '{}'", inputName); + Gson gson = new Gson(); + Type type = new TypeToken>(){}.getType(); + String stringValue = gson.toJson(value, type); + operationInput.setValue(stringValue); + } + if (value instanceof String) { + final String stringValue = (String) value; + operationInput.setDefaultValue(stringValue); + operationInput.setToscaDefaultValue(stringValue); + operationInput.setValue(stringValue); + } + } + + private Optional handleOperationImplementation( + final Map operationDefinitionMap + ) { + if (!operationDefinitionMap.containsKey(IMPLEMENTATION.getElementName())) { + return Optional.empty(); + } + final ArtifactDataDefinition artifactDataDefinition = new ArtifactDataDefinition(); + if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof Map && + ((Map)operationDefinitionMap.get(IMPLEMENTATION.getElementName())).containsKey("primary")) { + Map implDetails = (Map) ((Map)operationDefinitionMap.get(IMPLEMENTATION.getElementName())).get("primary"); + + if (implDetails.get("file") != null) { + final String file = implDetails.get("file").toString(); + artifactDataDefinition.setArtifactName(generateArtifactName(file)); + } + if (implDetails.get("type") != null) { + artifactDataDefinition.setArtifactType(implDetails.get("type").toString()); + } + if (implDetails.get("artifact_version") != null) { + artifactDataDefinition.setArtifactVersion(implDetails.get("artifact_version").toString()); + } + + if(implDetails.get("properties") instanceof Map) { + List operationProperties = artifactDataDefinition.getProperties() == null ? new ArrayList<>() : artifactDataDefinition.getProperties(); + Map properties = (Map) implDetails.get("properties"); + properties.forEach((k,v) -> { + ToscaPropertyType type = getTypeFromObject(v); + if (type != null) { + PropertyDataDefinition propertyDef = new PropertyDataDefinition(); + propertyDef.setName(k); + propertyDef.setValue(v.toString()); + artifactDataDefinition.addProperty(propertyDef); + } + }); + } + } + if (operationDefinitionMap.get(IMPLEMENTATION.getElementName()) instanceof String) { + final String implementation = (String) operationDefinitionMap.get(IMPLEMENTATION.getElementName()); + artifactDataDefinition.setArtifactName(generateArtifactName(implementation)); + } + return Optional.of(artifactDataDefinition); + } + + private String generateArtifactName(final String name) { + if (OperationArtifactUtil.artifactNameIsALiteralValue(name)) { + return name; + } else { + return QUOTE + name + QUOTE; + } + } + + private ToscaPropertyType getTypeFromObject(final Object value) { + if (value instanceof String) { + return ToscaPropertyType.STRING; + } + if (value instanceof Integer) { + return ToscaPropertyType.INTEGER; + } + if (value instanceof Boolean) { + return ToscaPropertyType.BOOLEAN; + } + if (value instanceof Float || value instanceof Double) { + return ToscaPropertyType.FLOAT; + } + return null; + } + @SuppressWarnings("unchecked") private boolean containsGetInput(Object propValue) { return ((Map) propValue).containsKey(GET_INPUT.getElementName()) || ImportUtils.containsGetInput(propValue); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java index 029c32930e..291e973155 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java @@ -159,6 +159,12 @@ public class InterfaceDefinitionHandler { final OperationDataDefinition operation = new OperationDataDefinition(); operation.setUniqueId(UUID.randomUUID().toString()); operation.setName(operationName); + Object operationDescription = operationDefinitionMap.get( + DESCRIPTION.getElementName() + ); + if (null != operationDescription) { + operation.setDescription(operationDescription.toString()); + } operation.setImplementation(handleOperationImplementation(operationDefinitionMap).orElse(new ArtifactDataDefinition())); if (operationDefinitionMap.containsKey(INPUTS.getElementName())) { final Map interfaceInputs = (Map) operationDefinitionMap.get(INPUTS.getElementName()); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index 7b328f755d..1cd322c047 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -68,6 +68,8 @@ import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition; import org.openecomp.sdc.be.datatypes.elements.PolicyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; @@ -89,6 +91,7 @@ import org.openecomp.sdc.be.model.DataTypeDefinition; import org.openecomp.sdc.be.model.DistributionStatusEnum; import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; import org.openecomp.sdc.be.model.LifecycleStateEnum; import org.openecomp.sdc.be.model.NodeTypeDefinition; @@ -108,6 +111,7 @@ import org.openecomp.sdc.be.model.Resource; import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.UploadAttributeInfo; import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; +import org.openecomp.sdc.be.model.UploadInterfaceInfo; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; import org.openecomp.sdc.be.model.UploadPropInfo; import org.openecomp.sdc.be.model.UploadReqInfo; @@ -1080,7 +1084,7 @@ public class ServiceImportBusinessLogic { List relations = new ArrayList<>(); Map> instInputs = new HashMap<>(); Map instNodeFilter = new HashMap<>(); - + Map> instInterfaces = new HashMap<>(); log.debug("enter ServiceImportBusinessLogic createResourceInstancesRelations#createResourceInstancesRelations - Before get all datatypes. "); final ApplicationDataTypeCache applicationDataTypeCache = serviceBusinessLogic.applicationDataTypeCache; if (applicationDataTypeCache != null) { @@ -1088,7 +1092,8 @@ public class ServiceImportBusinessLogic { uploadResInstancesMap.values().forEach( i -> processComponentInstance(yamlName, finalResource, componentInstancesList, componentsUtils.getAllDataTypes(applicationDataTypeCache, finalResource.getModel()), instProperties, instCapabilities, - instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, instInputs, instNodeFilter, i)); + instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, instInputs, instNodeFilter, + instInterfaces, i)); } serviceImportParseLogic.associateComponentInstancePropertiesToComponent(yamlName, resource, instProperties); serviceImportParseLogic.associateComponentInstanceInputsToComponent(yamlName, resource, instInputs); @@ -1444,6 +1449,7 @@ public class ServiceImportBusinessLogic { List relations = new ArrayList<>(); Map> instInputs = new HashMap<>(); Map instNodeFilter = new HashMap<>(); + Map> instInterfaces = new HashMap<>(); log.debug("enter ServiceImportBusinessLogic createServiceInstancesRelations#createResourceInstancesRelations - Before get all datatypes. "); final ApplicationDataTypeCache applicationDataTypeCache = serviceBusinessLogic.applicationDataTypeCache; if (applicationDataTypeCache != null) { @@ -1454,10 +1460,16 @@ public class ServiceImportBusinessLogic { i -> processComponentInstance(yamlName, service1, componentInstancesList, allDataTypesMap, instProperties, instCapabilities, instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, instInputs, - instNodeFilter, i)); + instNodeFilter, instInterfaces, i) + ); } updatePropertyToscaFunctionData(service, instProperties, instAttributes); serviceImportParseLogic.associateComponentInstancePropertiesToComponent(yamlName, service, instProperties); + serviceImportParseLogic.associateComponentInstanceInterfacesToComponent( + yamlName, + service, + instInterfaces + ); serviceImportParseLogic.associateComponentInstanceInputsToComponent(yamlName, service, instInputs); serviceImportParseLogic.associateCINodeFilterToComponent(yamlName, service, instNodeFilter); serviceImportParseLogic.associateDeploymentArtifactsToInstances(user, yamlName, service, instDeploymentArtifacts); @@ -1517,6 +1529,7 @@ public class ServiceImportBusinessLogic { Map> instAttributes, Map originCompMap, Map> instInputs, Map instNodeFilter, + Map> instInterfaces, UploadComponentInstanceInfo uploadComponentInstanceInfo) { log.debug("enter ServiceImportBusinessLogic processComponentInstance"); Optional currentCompInstanceOpt = componentInstancesList.stream() @@ -1551,6 +1564,19 @@ public class ServiceImportBusinessLogic { if (uploadComponentInstanceInfo.getUploadNodeFilterInfo() != null) { instNodeFilter.put(resourceInstanceId, uploadComponentInstanceInfo.getUploadNodeFilterInfo()); } + if (MapUtils.isNotEmpty(uploadComponentInstanceInfo.getInterfaces())) { + + ResponseFormat addInterfacesToRiRes = addInterfaceValuesToRi( + uploadComponentInstanceInfo, + component, + originResource, + currentCompInstance, + instInterfaces + ); + if (addInterfacesToRiRes.getStatus() != 200) { + throw new ComponentException(addInterfacesToRiRes); + } + } if (originResource.getResourceType() != ResourceTypeEnum.VF) { ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, component, originResource, currentCompInstance, instProperties, allDataTypes); @@ -1708,6 +1734,96 @@ public class ServiceImportBusinessLogic { return componentsUtils.getResponseFormat(ActionStatus.OK); } + protected ResponseFormat addInterfaceValuesToRi( + UploadComponentInstanceInfo uploadComponentInstanceInfo, + Component component, + Resource originResource, ComponentInstance currentCompInstance, + Map> instInterfaces + ) { + Map instanceInterfacesMap = uploadComponentInstanceInfo.getInterfaces(); + Map currInterfacesMap = new HashMap<>(); + Map interfacesFromNodeType = originResource.getInterfaces(); + if ((MapUtils.isNotEmpty(instanceInterfacesMap)) && (MapUtils.isEmpty(interfacesFromNodeType))) { + log.debug("failed to find interfaces "); + return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT); + } + if (interfacesFromNodeType == null || interfacesFromNodeType.isEmpty()) { + return componentsUtils.getResponseFormat(ActionStatus.OK); + } + for (Map.Entry entryInstances : interfacesFromNodeType.entrySet()) { + String interfaceName = entryInstances.getKey().substring(entryInstances.getKey().lastIndexOf(".") + 1); + if (!currInterfacesMap.containsKey(interfaceName)) { + currInterfacesMap.put(interfaceName, entryInstances.getValue()); + } + } + + Map instInterfacesMap = new HashMap<>(); + if (MapUtils.isNotEmpty(instanceInterfacesMap)) { + for (UploadInterfaceInfo uploadInterfaceInfo : instanceInterfacesMap.values()) { + String interfaceName = uploadInterfaceInfo.getName(); + if (!currInterfacesMap.containsKey(interfaceName)) { + log.debug("failed to find interface {} ", interfaceName); + return componentsUtils.getResponseFormat(ActionStatus.INTERFACE_NOT_FOUND_IN_COMPONENT, interfaceName); + } + InterfaceDefinition currentInterfaceDef = currInterfacesMap.get(interfaceName); + Map operationsToAdd = new HashMap<>(); + + Map operations = uploadInterfaceInfo.getOperations(); + for (Map.Entry operation : operations.entrySet()) { + OperationDataDefinition templateOperation = currentInterfaceDef.getOperationsMap().get(operation.getKey()); + OperationDataDefinition instanceOperation = operation.getValue(); + //Inputs + ListDataDefinition instanceInputs = instanceOperation.getInputs(); + mergeOperationInputDefinitions(templateOperation.getInputs(), instanceInputs); + templateOperation.setInputs(instanceInputs); + //Implementation + templateOperation.setImplementation(instanceOperation.getImplementation()); + //Description + templateOperation.setDescription(instanceOperation.getDescription()); + operationsToAdd.put(operation.getKey(), templateOperation); + } + InterfaceDefinition interfaceDef = new InterfaceDefinition(); + interfaceDef.setModel(component.getModel()); + interfaceDef.setType(currentInterfaceDef.getType()); + interfaceDef.setUniqueId(currentInterfaceDef.getType()); + interfaceDef.setDescription(uploadInterfaceInfo.getDescription()); + interfaceDef.setOperations(operationsToAdd); + instInterfacesMap.put(interfaceName, interfaceDef); + currInterfacesMap.remove(interfaceName); + } + } + if (!currInterfacesMap.isEmpty()) { + for (InterfaceDefinition value : currInterfacesMap.values()) { + instInterfacesMap.put(value.getUniqueId(), value); + } + } + instInterfaces.put(currentCompInstance.getUniqueId(), instInterfacesMap); + return componentsUtils.getResponseFormat(ActionStatus.OK); + } + + private void mergeOperationInputDefinitions(ListDataDefinition inputsFromNodeType, + ListDataDefinition instanceInputs) { + instanceInputs.getListToscaDataDefinition().forEach( + instanceInput -> inputsFromNodeType.getListToscaDataDefinition().stream().filter( + templateInput -> templateInput.getName().equals(instanceInput.getName()) + ).forEach( + newInstanceInput -> { + instanceInput.setSourceProperty(newInstanceInput.getSourceProperty()); + instanceInput.setSource(newInstanceInput.getSource()); + instanceInput.setType(newInstanceInput.getType()); + } + ) + ); + ListDataDefinition newInputsToAdd = new ListDataDefinition<>(); + instanceInputs.getListToscaDataDefinition().stream() + .filter(instanceInput -> inputsFromNodeType.getListToscaDataDefinition().stream().noneMatch( + inputFromNodeType -> inputFromNodeType.getName().equals(instanceInput.getName()) + )) + .forEach(oldInput -> { + oldInput.setType("string"); + }); + } + protected void processComponentInstanceCapabilities(Map allDataTypes, Map>> instCapabilties, UploadComponentInstanceInfo uploadComponentInstanceInfo, diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java index 507f4ad32c..8cc5bd6fcb 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java @@ -15,22 +15,7 @@ */ package org.openecomp.sdc.be.components.impl; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; -import static org.apache.commons.collections.CollectionUtils.isNotEmpty; - import fj.data.Either; -import java.util.ArrayList; -import java.util.EnumMap; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; import lombok.Getter; import org.apache.commons.codec.binary.Base64; import org.apache.commons.collections.CollectionUtils; @@ -52,6 +37,7 @@ import org.openecomp.sdc.be.datatypes.elements.GetInputValueDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition; import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition; import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition; import org.openecomp.sdc.be.datatypes.elements.RequirementSubstitutionFilterPropertyDataDefinition; @@ -88,6 +74,7 @@ import org.openecomp.sdc.be.model.Service; import org.openecomp.sdc.be.model.UploadCapInfo; import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; import org.openecomp.sdc.be.model.UploadInfo; +import org.openecomp.sdc.be.model.UploadInterfaceInfo; import org.openecomp.sdc.be.model.UploadNodeFilterInfo; import org.openecomp.sdc.be.model.UploadPropInfo; import org.openecomp.sdc.be.model.UploadReqInfo; @@ -116,6 +103,22 @@ import org.openecomp.sdc.exception.ResponseFormat; import org.yaml.snakeyaml.DumperOptions; import org.yaml.snakeyaml.Yaml; +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; + +import static java.util.stream.Collectors.joining; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toMap; +import static org.apache.commons.collections.CollectionUtils.isNotEmpty; + @Getter @org.springframework.stereotype.Component public class ServiceImportParseLogic { @@ -2003,6 +2006,32 @@ public class ServiceImportParseLogic { } } + public void associateComponentInstanceInterfacesToComponent( + String yamlName, + Service service, + Map> instInterfaces + ) { + if (MapUtils.isNotEmpty(instInterfaces)) { + Either, StorageOperationStatus> addInterfaceToInst = + toscaOperationFacade + .associateComponentInstanceInterfacesToComponent( + instInterfaces, + service.getUniqueId() + ); + if (addInterfaceToInst.isRight()) { + log.error("failed to associate interfaces value of service {}, status is {}", service.getUniqueId(), addInterfaceToInst.right().value()); + throw new ComponentException( + componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse( + addInterfaceToInst.right().value() + ), + yamlName + ) + ); + } + } + } + public void associateDeploymentArtifactsToInstances(User user, String yamlName, Resource resource, Map> instDeploymentArtifacts) { StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user); diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java index 967beb2235..df3dd1f0d6 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java @@ -20,25 +20,6 @@ package org.openecomp.sdc.be.components.csar; -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.when; -import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ARTIFACTS; - -import java.io.File; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; import mockit.Deencapsulation; import org.apache.commons.collections.MapUtils; import org.apache.commons.lang3.StringUtils; @@ -75,6 +56,25 @@ import org.openecomp.sdc.common.zip.ZipUtils; import org.openecomp.sdc.common.zip.exception.ZipException; import org.springframework.test.util.ReflectionTestUtils; +import java.io.File; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.when; +import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ARTIFACTS; + @ExtendWith(MockitoExtension.class) public class YamlTemplateParsingHandlerTest { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java index 0ff1d698c0..bbbbcfc260 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java @@ -108,7 +108,7 @@ class InterfaceDefinitionHandlerTest { @Test void testCreateWithOperationSuccess() throws FileNotFoundException { final Map load = loadYaml(Paths.get("interfaceDefinition-tosca1.3.yaml")); - final InterfaceDefinition actualInterfaceDefinition = interfaceDefinitionHandler.create(load, StringUtils.EMPTY); + final InterfaceDefinition actualInterfaceDefinition = interfaceDefinitionHandler.create( load, StringUtils.EMPTY); assertInterfaceDefinition(actualInterfaceDefinition); } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java index 3671ba7828..e5a4592b51 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java @@ -878,7 +878,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Assertions.assertNotNull(yamlName); sIBL.processComponentInstance(yamlName, resource, componentInstancesList, allDataTypes.left().value(), instProperties, instCapabilties, instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, - originCompMap, instInputs, instNodeFilter, uploadComponentInstanceInfo); + originCompMap, instInputs, instNodeFilter, null, uploadComponentInstanceInfo); } @Test @@ -904,7 +904,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Assertions.assertThrows(ComponentException.class, () -> sIBL.processComponentInstance(yamlName, resource, componentInstancesList, null, instProperties, instCapabilties, instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, - instInputs, instNodeFilter, uploadComponentInstanceInfo)); + instInputs, instNodeFilter, null, uploadComponentInstanceInfo)); } @Test @@ -1209,7 +1209,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest sIBL.processComponentInstance(yamlName, service, componentInstancesList, allDataTypes.left().value(), instProperties, instCapabilties, instRequirements, instDeploymentArtifacts, - instArtifacts, instAttributes, originCompMap, instInputs, instNodeFilter, + instArtifacts, instAttributes, originCompMap, instInputs, instNodeFilter, null, uploadComponentInstanceInfo); } @@ -1236,7 +1236,7 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Assertions.assertThrows(ComponentException.class, () -> sIBL.processComponentInstance(yamlName, service, componentInstancesList, null, instProperties, instCapabilties, instRequirements, instDeploymentArtifacts, instArtifacts, instAttributes, originCompMap, - instInputs, instNodeFilter, uploadComponentInstanceInfo)); + instInputs, instNodeFilter, null, uploadComponentInstanceInfo)); } @Test -- cgit 1.2.3-korg