Service Import - Node Template Interface Definitions 33/130033/15
authorfranciscovila <javier.paradela.vila@est.tech>
Tue, 26 Jul 2022 13:49:32 +0000 (14:49 +0100)
committerMichael Morris <michael.morris@est.tech>
Mon, 15 Aug 2022 11:24:12 +0000 (11:24 +0000)
Add Node Template Interface Definitions when
importing a service

Issue-ID: SDC-4113
Signed-off-by: franciscovila <javier.paradela.vila@est.tech>
Change-Id: I28bcb120ebd25b0baa4e62404d3fe38ce3a3706f

13 files changed:
catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportParseLogic.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/YamlTemplateParsingHandlerTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandlerTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInterfaceInfo.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/TopologyTemplateOperation.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/jsonjanusgraph/operations/ToscaOperationFacade.java
common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/MapInterfaceDataDefinition.java
integration-tests/src/test/java/org/onap/sdc/frontend/ci/tests/execute/sanity/ImportVfcUiTest.java

index cbba46f..ee31112 100644 (file)
@@ -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<String, UploadComponentInstanceInfo> getInstances(Map<String, Object> toscaJson,
-                                                                  Map<String, String> createdNodesToscaResourceNames) {
-        Map<String, Object> nodeTemplates = findFirstToscaMapElement(toscaJson, NODE_TEMPLATES).left().on(err -> new HashMap<>());
+    private Map<String, UploadComponentInstanceInfo> getInstances(
+            Map<String, Object> toscaJson,
+            Map<String, String> createdNodesToscaResourceNames
+    ) {
+        Map<String, Object> 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<String, UploadComponentInstanceInfo> getInstances(Map<String, Object> toscaJson, Map<String, String> createdNodesToscaResourceNames,
-                                                                  Map<String, Object> nodeTemplates) {
+    private Map<String, UploadComponentInstanceInfo> getInstances(
+            Map<String, Object> toscaJson,
+            Map<String, String> createdNodesToscaResourceNames,
+            Map<String, Object> nodeTemplates
+    ) {
         Map<String, Object> 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<String, Object> nodeTemplateJsonEntry,
-                                                                         Map<String, Object> substitutionMappings,
-                                                                         Map<String, String> createdNodesToscaResourceNames) {
+    private UploadComponentInstanceInfo buildModuleComponentInstanceInfo(
+            Map.Entry<String, Object> nodeTemplateJsonEntry,
+            Map<String, Object> substitutionMappings,
+            Map<String, String> 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<String, Object> nodeTemplateJsonMap
+    ){
+        if (nodeTemplateJsonMap.containsKey(INTERFACES.getElementName())) {
+            Map<String, UploadInterfaceInfo> interfaces = buildInterfacesModuleFromYaml(
+                    nodeTemplateJsonMap
+            );
+            if (!interfaces.isEmpty()) {
+                nodeTemplateInfo.setInterfaces(interfaces);
+            }
+        }
+    }
+
     private void setCapabilities(UploadComponentInstanceInfo nodeTemplateInfo, Map<String, Object> nodeTemplateJsonMap) {
         if (nodeTemplateJsonMap.containsKey(CAPABILITIES.getElementName())) {
             Map<String, List<UploadCapInfo>> eitherCapRes = createCapModuleFromYaml(nodeTemplateJsonMap);
@@ -1044,7 +1092,8 @@ public class YamlTemplateParsingHandler {
         return regTemplateInfo;
     }
 
-    private Map<String, UploadAttributeInfo> buildAttributeModuleFromYaml(Map<String, Object> nodeTemplateJsonMap) {
+    private Map<String, UploadAttributeInfo> buildAttributeModuleFromYaml(
+            Map<String, Object> nodeTemplateJsonMap) {
         Map<String, UploadAttributeInfo> moduleAttribute = new HashMap<>();
         Either<Map<String, Object>, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(nodeTemplateJsonMap, ATTRIBUTES);
         if (toscaAttributes.isLeft()) {
@@ -1070,6 +1119,20 @@ public class YamlTemplateParsingHandler {
         return moduleProp;
     }
 
+    private Map<String, UploadInterfaceInfo> buildInterfacesModuleFromYaml(
+            Map<String, Object> nodeTemplateJsonMap
+    ) {
+        Map<String, UploadInterfaceInfo> moduleInterfaces = new HashMap<>();
+        Either<Map<String, Object>, ResultStatusEnum> toscaInterfaces = findFirstToscaMapElement(nodeTemplateJsonMap, INTERFACES);
+        if (toscaInterfaces.isLeft()) {
+            Map<String, Object> jsonInterfaces = toscaInterfaces.left().value();
+            for (Map.Entry<String, Object> jsonInterfacesObj : jsonInterfaces.entrySet()) {
+                addInterfaces(moduleInterfaces, jsonInterfacesObj);
+            }
+        }
+        return moduleInterfaces;
+    }
+
     private void addProperty(Map<String, List<UploadPropInfo>> moduleProp, Map.Entry<String, Object> jsonPropObj) {
         UploadPropInfo propertyDef = buildProperty(jsonPropObj.getKey(), jsonPropObj.getValue());
         if (moduleProp.containsKey(propertyDef.getName())) {
@@ -1081,6 +1144,11 @@ public class YamlTemplateParsingHandler {
         }
     }
 
+    private void addInterfaces(Map<String, UploadInterfaceInfo> moduleInterface, Map.Entry<String, Object> 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<String, OperationDataDefinition> operations = new HashMap<>();
+        if (interfaceValue instanceof Map) {
+            Map<String, Object> operationsMap = (Map<String, Object>) interfaceValue;
+            for (Map.Entry<String, Object> operationEntry : operationsMap.entrySet()) {
+                OperationDataDefinition operationDef = new OperationDataDefinition();
+                operationDef.setName(operationEntry.getKey());
+                Map<String, Object> operationValue = (Map<String, Object>) 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<String, Object> interfaceInputs = (Map<String, Object>) operationValue.get(INPUTS.getElementName());
+                    operationDef.setInputs(handleInterfaceOperationInputs(interfaceInputs));
+                }
+                operations.put(operationEntry.getKey(), operationDef);
+            }
+            interfaceDef.setOperations(operations);
+            if (operationsMap.containsKey(TYPE.getElementName())) {
+                interfaceDef.setType(((Map<String, Object>) interfaceValue).get(TYPE.getElementName()).toString());
+            }
+        }
+        return interfaceDef;
+    }
+
+    private ListDataDefinition<OperationInputDefinition> handleInterfaceOperationInputs(final Map<String, Object> interfaceInputs) {
+        final ListDataDefinition<OperationInputDefinition> inputs = new ListDataDefinition<>();
+        for (final Entry<String, Object> 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<LinkedHashMap<String, Object>>(){}.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<ArtifactDataDefinition> handleOperationImplementation(
+        final Map<String, Object> 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<String, Object> 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<PropertyDataDefinition> operationProperties = artifactDataDefinition.getProperties() == null ? new ArrayList<>() : artifactDataDefinition.getProperties();
+                Map<String, Object> properties = (Map<String, Object>) 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<String, Object>) propValue).containsKey(GET_INPUT.getElementName()) || ImportUtils.containsGetInput(propValue);
index 029c329..291e973 100644 (file)
@@ -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<String, Object> interfaceInputs = (Map<String, Object>) operationDefinitionMap.get(INPUTS.getElementName());
index 7b328f7..1cd322c 100644 (file)
@@ -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<RequirementCapabilityRelDef> relations = new ArrayList<>();
         Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
         Map<String, UploadNodeFilterInfo> instNodeFilter = new HashMap<>();
-
+        Map<String, Map<String, InterfaceDefinition>> 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<RequirementCapabilityRelDef> relations = new ArrayList<>();
         Map<String, List<ComponentInstanceInput>> instInputs = new HashMap<>();
         Map<String, UploadNodeFilterInfo> instNodeFilter = new HashMap<>();
+        Map<String, Map<String, InterfaceDefinition>> 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<String, List<AttributeDefinition>> instAttributes, Map<String, Resource> originCompMap,
                                             Map<String, List<ComponentInstanceInput>> instInputs,
                                             Map<String, UploadNodeFilterInfo> instNodeFilter,
+                                            Map<String, Map<String, InterfaceDefinition>> instInterfaces,
                                             UploadComponentInstanceInfo uploadComponentInstanceInfo) {
         log.debug("enter ServiceImportBusinessLogic processComponentInstance");
         Optional<ComponentInstance> 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<String, Map<String, InterfaceDefinition>> instInterfaces
+    ) {
+        Map<String, UploadInterfaceInfo> instanceInterfacesMap = uploadComponentInstanceInfo.getInterfaces();
+        Map<String, InterfaceDefinition> currInterfacesMap = new HashMap<>();
+        Map<String, InterfaceDefinition> 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<String, InterfaceDefinition> entryInstances : interfacesFromNodeType.entrySet()) {
+            String interfaceName = entryInstances.getKey().substring(entryInstances.getKey().lastIndexOf(".") + 1);
+            if (!currInterfacesMap.containsKey(interfaceName)) {
+                currInterfacesMap.put(interfaceName, entryInstances.getValue());
+            }
+        }
+
+        Map<String, InterfaceDefinition> 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<String, OperationDataDefinition> operationsToAdd = new HashMap<>();
+
+                Map<String, OperationDataDefinition> operations = uploadInterfaceInfo.getOperations();
+                for (Map.Entry<String, OperationDataDefinition> operation : operations.entrySet()) {
+                    OperationDataDefinition templateOperation = currentInterfaceDef.getOperationsMap().get(operation.getKey());
+                    OperationDataDefinition instanceOperation = operation.getValue();
+                    //Inputs
+                    ListDataDefinition<OperationInputDefinition> 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<OperationInputDefinition> inputsFromNodeType,
+                                                ListDataDefinition<OperationInputDefinition> 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<OperationInputDefinition> 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<String, DataTypeDefinition> allDataTypes,
                                                         Map<ComponentInstance, Map<String, List<CapabilityDefinition>>> instCapabilties,
                                                         UploadComponentInstanceInfo uploadComponentInstanceInfo,
index 507f4ad..8cc5bd6 100644 (file)
  */
 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<String, Map<String, InterfaceDefinition>> instInterfaces
+    ) {
+        if (MapUtils.isNotEmpty(instInterfaces)) {
+            Either<Map<String, MapInterfaceDataDefinition>, 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<String, Map<String, ArtifactDefinition>> instDeploymentArtifacts) {
         StorageOperationStatus addArtToInst = toscaOperationFacade.associateDeploymentArtifactsToInstances(instDeploymentArtifacts, resource, user);
index 967beb2..df3dd1f 100644 (file)
 
 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 {
 
index 0ff1d69..bbbbcfc 100644 (file)
@@ -108,7 +108,7 @@ class InterfaceDefinitionHandlerTest {
     @Test
     void testCreateWithOperationSuccess() throws FileNotFoundException {
         final Map<String, Object> 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);
     }
 
index 3671ba7..e5a4592 100644 (file)
@@ -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
index ef9f1f1..5aad2fb 100644 (file)
  */
 package org.openecomp.sdc.be.model;
 
+import lombok.Getter;
+import lombok.Setter;
+
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
-import lombok.Getter;
-import lombok.Setter;
 import org.openecomp.sdc.be.ui.model.OperationUi;
 
 @Getter
@@ -40,6 +41,7 @@ public class UploadComponentInstanceInfo {
     private Map<String, String> capabilitiesNamesToUpdate;
     private Map<String, String> requirementsNamesToUpdate;
     private Collection<String> directives;
+    private Map<String, UploadInterfaceInfo> interfaces;
     private UploadNodeFilterInfo uploadNodeFilterInfo;
     private Map<String, List<OperationUi>> operations;
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInterfaceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInterfaceInfo.java
new file mode 100644 (file)
index 0000000..1a05ace
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation
+ *  ================================================================================
+ *  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.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ *
+ *
+ */
+package org.openecomp.sdc.be.model;
+
+import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
+import java.util.HashMap;
+import java.util.Map;
+
+public class UploadInterfaceInfo extends UploadInfo {
+    private Object value;
+    private String description;
+    private String type;
+    private Map<String, OperationDataDefinition> operations;
+
+    public Map<String, OperationDataDefinition> getOperations() {
+        if (operations == null) {
+            operations = new HashMap<>();
+        }
+        return operations;
+    }
+
+    public void setOperations(Map<String, OperationDataDefinition> operations) {
+        this.operations = operations;
+    }
+
+    public Object getValue() {
+        return value;
+    }
+
+    public void setValue(Object value) {
+        this.value = value;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public void setType(String type) {
+        this.type = type;
+    }
+}
index dcd8011..91176a9 100644 (file)
@@ -385,6 +385,23 @@ public class TopologyTemplateOperation extends ToscaElementOperation {
         return StorageOperationStatus.OK;
     }
 
+    public StorageOperationStatus associateInstInterfacesToComponent(
+            GraphVertex nodeTypeVertex,
+            Map<String, MapInterfaceDataDefinition> instInterfaces
+    ) {
+        if (instInterfaces != null && !instInterfaces.isEmpty()) {
+            Either<GraphVertex, StorageOperationStatus> associateElementToData = associateElementToData(
+                    nodeTypeVertex,
+                    VertexTypeEnum.INST_INTERFACES,
+                    EdgeLabelEnum.INST_INTERFACES,
+                    instInterfaces);
+            if (associateElementToData.isRight()) {
+                return associateElementToData.right().value();
+            }
+        }
+        return StorageOperationStatus.OK;
+    }
+
     public StorageOperationStatus associateInstGroupsToComponent(GraphVertex nodeTypeVertex, Map<String, MapGroupsDataDefinition> instGroups) {
         if (instGroups != null && !instGroups.isEmpty()) {
             Either<GraphVertex, StorageOperationStatus> assosiateElementToData = associateElementToData(nodeTypeVertex, VertexTypeEnum.INST_GROUPS,
index 8c08a3d..b35ae1e 100644 (file)
  */
 package org.openecomp.sdc.be.model.jsonjanusgraph.operations;
 
-import static java.util.Objects.requireNonNull;
-import static org.apache.commons.collections.CollectionUtils.isEmpty;
-import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
-import static org.janusgraph.core.attribute.Text.REGEX;
-
 import com.vdurmont.semver4j.Semver;
 import com.vdurmont.semver4j.Semver.SemverType;
 import fj.data.Either;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.EnumMap;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-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.TreeSet;
-import java.util.function.BiPredicate;
-import java.util.stream.Collectors;
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.MapUtils;
 import org.apache.commons.lang3.StringUtils;
@@ -68,6 +44,8 @@ import org.openecomp.sdc.be.datatypes.elements.CapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.InputDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.ListRequirementDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.MapArtifactDataDefinition;
@@ -77,6 +55,7 @@ import org.openecomp.sdc.be.datatypes.elements.MapInterfaceDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.MapListCapabilityDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.MapListRequirementDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.MapPropertiesDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.RequirementDataDefinition;
 import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum;
@@ -113,6 +92,7 @@ import org.openecomp.sdc.be.model.RequirementCapabilityRelDef;
 import org.openecomp.sdc.be.model.RequirementDefinition;
 import org.openecomp.sdc.be.model.Resource;
 import org.openecomp.sdc.be.model.Service;
+import org.openecomp.sdc.be.model.UploadInterfaceInfo;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.catalog.CatalogComponent;
 import org.openecomp.sdc.be.model.jsonjanusgraph.config.ContainerInstanceTypesData;
@@ -134,6 +114,31 @@ import org.openecomp.sdc.common.log.wrappers.Logger;
 import org.openecomp.sdc.common.util.ValidationUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+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.TreeSet;
+import java.util.function.BiPredicate;
+import java.util.stream.Collectors;
+
+import static java.util.Objects.requireNonNull;
+import static org.apache.commons.collections.CollectionUtils.isEmpty;
+import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.janusgraph.core.attribute.Text.REGEX;
+
 @org.springframework.stereotype.Component("tosca-operation-facade")
 public class ToscaOperationFacade {
 
@@ -1665,6 +1670,48 @@ public class ToscaOperationFacade {
         return Either.right(status);
     }
 
+    public Either<Map<String, MapInterfaceDataDefinition>, StorageOperationStatus> associateComponentInstanceInterfacesToComponent(
+            Map<String, Map<String, InterfaceDefinition>> instInterfaces,
+            String componentId
+    ) {
+        Either<GraphVertex, JanusGraphOperationStatus> getVertexEither = janusGraphDao.getVertexById(
+                componentId,
+                JsonParseFlagEnum.NoParse
+        );
+        if (getVertexEither.isRight()) {
+            log.debug(
+                    COULDNT_FETCH_COMPONENT_WITH_AND_UNIQUE_ID_ERROR,
+                    componentId,
+                    getVertexEither.right().value()
+            );
+            return Either.right(
+                    DaoStatusConverter.convertJanusGraphStatusToStorageStatus(
+                            getVertexEither.right().value()
+                    )
+            );
+        }
+        GraphVertex vertex = getVertexEither.left().value();
+        Map<String, MapInterfaceDataDefinition> instInterfacesMap = new HashMap<>();
+        if (instInterfaces != null) {
+            MapInterfaceDataDefinition interfacesMap = new MapInterfaceDataDefinition();
+            for (Map.Entry<String, Map<String, InterfaceDefinition>> entryInstances : instInterfaces.entrySet()) {
+                Map<String, InterfaceDataDefinition> incomingInterfacesMap = entryInstances.getValue().entrySet().stream()
+                        .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue()));
+                interfacesMap.setMapToscaDataDefinition(incomingInterfacesMap);
+                instInterfacesMap.put(entryInstances.getKey(), interfacesMap);
+            }
+        }
+        StorageOperationStatus status = topologyTemplateOperation.associateInstInterfacesToComponent(
+                vertex,
+                instInterfacesMap
+        );
+        if (StorageOperationStatus.OK == status) {
+            log.debug(COMPONENT_CREATED_SUCCESSFULLY);
+            return Either.left(instInterfacesMap);
+        }
+        return Either.right(status);
+    }
+
     public Either<Map<String, List<ComponentInstanceInput>>, StorageOperationStatus> addComponentInstanceInputsToComponent(
         Component containerComponent, Map<String, List<ComponentInstanceInput>> instProperties) {
         requireNonNull(instProperties);
index 1b7c80b..069cbd7 100644 (file)
@@ -28,6 +28,12 @@ public class MapInterfaceDataDefinition extends MapDataDefinition<InterfaceDataD
         super(mapToscaDataDefinition);
     }
 
+    public void setMapToscaDataDefinition(
+            Map<String, InterfaceDataDefinition> mapToscaDataDefinition
+    ) {
+        this.mapToscaDataDefinition = mapToscaDataDefinition;
+    }
+
     @JsonValue
     @Override
     public Map<String, InterfaceDataDefinition> getMapToscaDataDefinition() {
index c8a45de..72810c5 100644 (file)
@@ -172,7 +172,7 @@ public class ImportVfcUiTest extends SetupCDTest {
     }
 
     private void checkInterfaceDefinitionData(final InterfaceDefinitionOperationsModal interfaceDefinitionOperationsModal) {
-        assertTrue(interfaceDefinitionOperationsModal.getDescription().isEmpty());
+        assertFalse(interfaceDefinitionOperationsModal.getDescription().isEmpty());
         assertEquals("path/to/my/implementation.sh", interfaceDefinitionOperationsModal.getImplementationName());
         final List<InputData> inputList = interfaceDefinitionOperationsModal.getInputs();
         assertTrue(inputList.stream().anyMatch(inputData -> "first".equals(inputData.getName())), "Input of name 'first' expected");