Handle 'get_input' syntax for layer_protocols in PnfExtCp type 29/91729/6
authorvasraz <vasyl.razinkov@est.tech>
Tue, 6 Aug 2019 09:44:08 +0000 (09:44 +0000)
committerOfir Sonsino <ofir.sonsino@intl.att.com>
Sun, 18 Aug 2019 06:53:04 +0000 (06:53 +0000)
Change-Id: I52f91e47dbda20c8c0701ee25f2eec5a83815112
Issue-ID: SDC-2427
Signed-off-by: vasraz <vasyl.razinkov@est.tech>
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java
common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/ToscaSolConverterPnf.java
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/java/org/openecomp/core/impl/ToscaSolConverterPnfTest.java
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsAndDuplicatedGetInput.yaml [new file with mode: 0644]
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsGetInput.yaml [new file with mode: 0644]
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/other/pnfDescriptor_PnfAnd2ExtCps.yaml
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsAndDuplicatedGetInput.yaml [new file with mode: 0644]
openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsGetInput.yaml [new file with mode: 0644]
openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java

index a764c89..b1356fc 100644 (file)
@@ -429,7 +429,7 @@ public abstract class BaseBusinessLogic {
         String type;
         String innerType = null;
         if (!propertyOperation.isPropertyTypeValid(property)) {
-            log.info("Invalid type for property {} type {}", property.getName(), property.getType());
+            log.info("Invalid type for property '{}' type '{}'", property.getName(), property.getType());
             ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName());
             return Either.right(responseFormat);
         }
@@ -438,13 +438,13 @@ public abstract class BaseBusinessLogic {
             ImmutablePair<String, Boolean> propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes);
             innerType = propertyInnerTypeValid.getLeft();
             if (!propertyInnerTypeValid.getRight()) {
-                log.info("Invalid inner type for property {} type {}, dataTypeCount {}", property.getName(), property.getType(), dataTypes.size());
+                log.info("Invalid inner type for property '{}' type '{}', dataTypeCount '{}'", property.getName(), property.getType(), dataTypes.size());
                 ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName());
                 return Either.right(responseFormat);
             }
         }
         if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) {
-            log.info("Invalid default value for property {} type {}", property.getName(), property.getType());
+            log.info("Invalid default value for property '{}' type '{}'", property.getName(), property.getType());
             ResponseFormat responseFormat;
             if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) {
                 responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType,
@@ -556,9 +556,10 @@ public abstract class BaseBusinessLogic {
         return Arrays.asList(enumValues).contains(enumFound);
     }
 
-    String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> allDataTypes) {
+    String validatePropValueBeforeCreate(IPropertyInputCommon property, String value, boolean isValidate,
+        Map<String, DataTypeDefinition> allDataTypes) {
         String propertyType = property.getType();
-        String updatedInnerType = updateInnerType(property, innerType);
+        String updatedInnerType = updateInnerType(property);
         Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value, isValidate, updatedInnerType, allDataTypes);
         String newValue = value;
         if (isValid.isRight()) {
@@ -583,7 +584,7 @@ public abstract class BaseBusinessLogic {
         return newValue;
     }
 
-    private String updateInnerType(IPropertyInputCommon property, String innerType) {
+    private String updateInnerType(IPropertyInputCommon property) {
         ToscaPropertyType type = ToscaPropertyType.isValidType(property.getType());
         if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) {
             SchemaDefinition def = property.getSchema();
@@ -598,7 +599,7 @@ public abstract class BaseBusinessLogic {
             }
             return propDef.getType();
         }
-        return innerType;
+        return null;
     }
 
     private void failOnIllegalArgument() {
index 5355ad9..c40c845 100644 (file)
@@ -2481,7 +2481,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
             }
         }
         property.setValue(value);
-        return validatePropValueBeforeCreate(property, value, isValidate, null, allDataTypes);
+        return validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
     }
 
     private Either<Resource, StorageOperationStatus> updateCalculatedCapReqWithSubstitutionMappings(Resource resource,
@@ -2736,7 +2736,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
         String innerType = null;
         property = new ComponentInstanceInput(curPropertyDef, value, null);
 
-        String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, innerType, allDataTypes);
+        String validPropertyVAlue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
 
         property.setValue(validPropertyVAlue);
 
@@ -2846,7 +2846,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic {
                 String innerType = null;
                 property = new ComponentInstanceProperty(curPropertyDef, value, null);
 
-                String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, innerType, allDataTypes);
+                String validatePropValue = validatePropValueBeforeCreate(property, value, isValidate, allDataTypes);
                 property.setValue(validatePropValue);
 
                 if (getInputs != null && !getInputs.isEmpty()) {
index 6f2cc9c..408fb50 100644 (file)
@@ -58,11 +58,14 @@ public class TypeUtils {
         TOSCA_VERSION("tosca_definitions_version"), TOPOLOGY_TEMPLATE("topology_template"), NODE_TYPES("node_types"), OCCURRENCES("occurrences"), NODE_TEMPLATES("node_templates"), GROUPS("groups"), INPUTS("inputs"),
         SUBSTITUTION_MAPPINGS("substitution_mappings"), NODE_TYPE("node_type"), DIRECTIVES("directives"),
         // Attributes
-        ATTRIBUTES("attributes"), LABEL("label"), HIDDEN("hidden"), IMMUTABLE("immutable"), GET_INPUT("get_input"), ANNOTATIONS("annotations");
+        ATTRIBUTES("attributes"), LABEL("label"), HIDDEN("hidden"), IMMUTABLE("immutable"), ANNOTATIONS("annotations"),
+        //functions
+        GET_INPUT("get_input");
+
 
         private String elementName;
 
-        ToscaTagNamesEnum(String elementName) {
+        ToscaTagNamesEnum(final String elementName) {
             this.elementName = elementName;
         }
 
index 0258b42..a3935ee 100644 (file)
 
 package org.openecomp.core.impl;
 
-import org.apache.commons.collections.MapUtils;
-import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
-import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
-import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
-import org.openecomp.core.converter.ServiceTemplateReaderService;
-import org.openecomp.sdc.tosca.services.DataModelUtil;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.CONSTRAINTS;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DEFAULT_VALUE;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.DESCRIPTION;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.ENTRY_SCHEMA;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.GET_INPUT;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.PROPERTIES;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.REQUIRED;
+import static org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum.TYPE;
 
+import java.util.AbstractMap;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
 import java.util.stream.Collectors;
+import org.apache.commons.collections.MapUtils;
+import org.onap.sdc.tosca.datatypes.model.Constraint;
+import org.onap.sdc.tosca.datatypes.model.EntrySchema;
+import org.onap.sdc.tosca.datatypes.model.NodeTemplate;
+import org.onap.sdc.tosca.datatypes.model.ParameterDefinition;
+import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
+import org.onap.sdc.tosca.datatypes.model.TopologyTemplate;
+import org.openecomp.core.converter.ServiceTemplateReaderService;
+import org.openecomp.sdc.tosca.services.DataModelUtil;
 
 public class ToscaSolConverterPnf extends AbstractToscaSolConverter {
 
     private static final String PNF_EXT_CP_TYPE = "tosca.nodes.nfv.PnfExtCp";
     private static final String EXT_CP_TYPE = "org.openecomp.resource.cp.v2.extCP";
     private static final String LAYER_PROTOCOLS = "layer_protocols";
+    private static final String ASSIGNMENT_METHOD = "assingment_method";
+    private static final String DHCP = "dhcp";
     private static final String IP_V4 = "ipv4";
     private static final String IP_V6 = "ipv6";
     private static final String IP_VERSION = "ip_version";
-    private static final String ASSIGNMENT_METHOD = "assingment_method";
-    private static final String DHCP = "dhcp";
+    private static final String IP_REQUIREMENTS = "ip_requirements";
+    private static final String IP_REQUIREMENTS_TYPE = "org.openecomp.datatypes.network.IpRequirements";
+    private ServiceTemplate serviceTemplate;
+    private ServiceTemplateReaderService readerService;
 
     /**
-     * For PNF the node templates are converted ETSI node types to ecomp node types
-     * All other data i.e. inputs, substitution mappings and outputs are simply dropped at this stage. The equivalent
-     * ecomp data will be added when the vsp is imported into the catalog.
-     * @param serviceTemplate
-     * @param readerService
+     * For PNF the node templates are converted ETSI node types to ecomp node types. All other data i.e. inputs,
+     * substitution mappings and outputs are simply dropped at this stage. The equivalent ecomp data will be added when
+     * the vsp is imported into the catalog.
+     *
+     * @param serviceTemplate - the service template
+     * @param readerService - the reader service
      */
     @Override
-    public void convertTopologyTemplate(ServiceTemplate serviceTemplate, ServiceTemplateReaderService readerService) {
-        convertNodeTemplatesToEcompTypes(serviceTemplate, readerService);
-        addEmptyNodeTemplatesIfNoneDefined(serviceTemplate);
+    public void convertTopologyTemplate(final ServiceTemplate serviceTemplate,
+            final ServiceTemplateReaderService readerService) {
+        this.serviceTemplate = serviceTemplate;
+        this.readerService = readerService;
+        convertNodeTemplatesToEcompTypes();
+        addEmptyNodeTemplatesIfNoneDefined();
     }
 
     /**
-     * PNF only has nfv.PNF and nfv.PnfExtCp types defined in ETSI SOL001 v2.5.1.
-     * - The PNF is mapped to the outer Abstract PNF container in ecomp model and hence nfv.PNF is dropped here.
-     * - nfv.PnfExtCp is mapped to ecomp v2.extCp type.
-     *
-     * @param serviceTemplate
-     * @param readerService
+     * Copies a input from the reader (input) to the service template (output)
+     * @param inputName     the name of the input to copy
      */
-    private void convertNodeTemplatesToEcompTypes(ServiceTemplate serviceTemplate,
-                                                  ServiceTemplateReaderService readerService) {
-        Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
-        if (MapUtils.isEmpty(nodeTemplates)) {
+    private void copyTopologyTemplateInput(final String inputName) {
+        final Map<String, Object> inputMap = readerService.getInputs();
+        if (MapUtils.isEmpty(inputMap)) {
             return;
         }
+        final Map propertyMap = (Map) inputMap.get(inputName);
+        final Object requiredObj = propertyMap.get(REQUIRED.getElementName());
+        final Object constraintsObj = propertyMap.get(CONSTRAINTS.getElementName());
+        final Object entrySchemaObj = propertyMap.get(ENTRY_SCHEMA.getElementName());
 
-        for (Map.Entry<String, Object> nodeTemplateEntry : nodeTemplates.entrySet()) {
-            Map<String, Object> inputNodeTemplate = (Map<String, Object>) nodeTemplateEntry.getValue();
-            if (PNF_EXT_CP_TYPE.equals((String) inputNodeTemplate.get("type"))) {
-                NodeTemplate nodeTemplate = convertToEcompConnectionPointNodeType(inputNodeTemplate);
-                DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(), nodeTemplate);
-            }
+        EntrySchema entrySchema = null;
+        if (entrySchemaObj instanceof Map) {
+            final Map entrySchemaMap = ((Map) entrySchemaObj);
+            entrySchema = parseEntrySchema(entrySchemaMap);
         }
-        addEmptyNodeTemplatesIfNoneDefined(serviceTemplate);
+        final ParameterDefinition parameterDefinition =
+            DataModelUtil.createParameterDefinition(
+                (String) propertyMap.get(TYPE.getElementName()),
+                (String) propertyMap.get(DESCRIPTION.getElementName()),
+                requiredObj instanceof Boolean ? (Boolean) requiredObj : null,
+                constraintsObj instanceof List ? (List<Constraint>) constraintsObj : null,
+                entrySchema,
+                propertyMap.get(DEFAULT_VALUE.getElementName()));
+
+        DataModelUtil
+            .addInputParameterToTopologyTemplate(serviceTemplate, inputName, parameterDefinition);
     }
 
+    /**
+     * PNF only has nfv.PNF and nfv.PnfExtCp types defined in ETSI SOL001 v2.5.1. - The PNF is mapped to the outer
+     * Abstract PNF container in ecomp model and hence nfv.PNF is dropped here. - nfv.PnfExtCp is mapped to ecomp
+     * v2.extCp type.
+     */
+    private void convertNodeTemplatesToEcompTypes() {
+        final Map<String, Object> nodeTemplates = readerService.getNodeTemplates();
+        if (MapUtils.isEmpty(nodeTemplates)) {
+            return;
+        }
+
+        nodeTemplates.entrySet().stream()
+            .filter(nodeTemplateEntry ->
+                PNF_EXT_CP_TYPE.equals(((Map<String, Object>) nodeTemplateEntry.getValue()).get(TYPE.getElementName())))
+            .forEach(nodeTemplateEntry ->
+                DataModelUtil.addNodeTemplate(serviceTemplate, nodeTemplateEntry.getKey(),
+                    convertToEcompConnectionPointNodeType((Map<String, Object>) nodeTemplateEntry.getValue())));
+    }
 
     /**
-     * Converts from the ETSI PnfExtCp node type to ecomp v2.extCP node type
-     * The following properties are mapped
-     * - layer_protocols is mapped to ip_requirements if it contains the values ipv4 and/or ipv6
-     * <p>
-     * All other data e.g. remaining properties, requirements, capabilities are
-     * not mapped over to ecomp equivalent
+     * Converts from the ETSI PnfExtCp node type to ecomp v2.extCP node type The following properties are mapped -
+     * layer_protocols is mapped to ip_requirements if it contains the values ipv4 and/or ipv6. All other data e.g.
+     * remaining properties, requirements, capabilities are not mapped over to ecomp equivalent
      *
-     * @param pnfExtCp
+     * @param pnfExtCp - the ETSI PnfExtCp map
      * @return ecomp v2.extCP node type
      */
-    private NodeTemplate convertToEcompConnectionPointNodeType(Map<String, Object> pnfExtCp) {
-        NodeTemplate nodeTemplate = new NodeTemplate();
+    private NodeTemplate convertToEcompConnectionPointNodeType(final Map<String, Object> pnfExtCp) {
+        final NodeTemplate nodeTemplate = new NodeTemplate();
         nodeTemplate.setType(EXT_CP_TYPE);
-        Map<String, Object> properties = (Map<String, Object>) pnfExtCp.get("properties");
-        for (Map.Entry<String, Object> property : properties.entrySet()) {
-            final String propertyName = property.getKey();
-            if (LAYER_PROTOCOLS.equals(propertyName)) {
-                List<Map<String, Object>> ipRequirements = convertToIpRequirementsProperty((List<String>) property.getValue());
-                if (isNotEmpty(ipRequirements)) {
-                    Map<String, Object> convertedProperties = new HashMap<>();
-                    convertedProperties.put("ip_requirements", ipRequirements);
-                    nodeTemplate.setProperties(convertedProperties);
+        final Map<String, Object> properties = (Map<String, Object>) pnfExtCp.get(PROPERTIES.getElementName());
+
+        properties.entrySet().stream()
+            .filter(propertyMap -> LAYER_PROTOCOLS.equals(propertyMap.getKey()))
+            .forEach(propertyMap -> {
+                final Object propertyValue = propertyMap.getValue();
+                if (propertyValue instanceof List) {
+                    // layer_protocols: [ ipv4, ipv6, ... ]
+                    final List<Map<String, Object>> ipRequirements =
+                        convertToIpRequirementsProperty((List<String>) propertyValue);
+                    if (!ipRequirements.isEmpty()) {
+                        final Map<String, Object> convertedProperties = new HashMap<>();
+                        convertedProperties.put(IP_REQUIREMENTS, ipRequirements);
+                        nodeTemplate.setProperties(convertedProperties);
+                    }
+                } else if (propertyValue instanceof AbstractMap) {
+                    final Map propertyValueMap = (Map) propertyValue;
+                    if (propertyValueMap.containsKey(GET_INPUT.getElementName())) {
+                        // layer_protocols: {get_input: anInputName}
+                        final Map<String, Object> convertedProperties = new HashMap<>();
+                        convertedProperties.put(IP_REQUIREMENTS, propertyValueMap);
+                        nodeTemplate.setProperties(convertedProperties);
+                        final String getInputValue = (String) propertyValueMap.get(GET_INPUT.getElementName());
+                        if (!isInputAlreadyAdded(getInputValue)) {
+                            copyTopologyTemplateInput(getInputValue);
+                            parseLayerProtocolsInputToIpRequirements(getInputValue);
+                        }
+                    }
                 }
-            }
-        }
+            });
         return nodeTemplate;
     }
 
-    private List<Map<String, Object>> convertToIpRequirementsProperty(List<String> layerProtocols) {
+    /**
+     * Checks if a topology template input was already added
+     *
+     * @param inputName     The name of the input to check
+     * @return
+     *  {@code true} if the input was found in the topology template structure
+     */
+    private boolean isInputAlreadyAdded(final String inputName) {
+        final TopologyTemplate topologyTemplate = serviceTemplate.getTopology_template();
+        if (topologyTemplate == null) {
+            return false;
+        }
+
+        final Map<String, ParameterDefinition> inputMap = topologyTemplate.getInputs();
+        if (MapUtils.isNotEmpty(inputMap)) {
+            return inputMap.keySet().contains(inputName);
+        }
+
+        return false;
+    }
+
+    /**
+     * Parses a layer_protocol input to org.openecomp.datatypes.network.IpRequirements ecomp type.
+     *
+     * @param inputName     The name of the input to parse
+     *
+     */
+    private void parseLayerProtocolsInputToIpRequirements(final String inputName) {
+        final TopologyTemplate topologyTemplate = serviceTemplate.getTopology_template();
+        final ParameterDefinition layerProtocolsInput = topologyTemplate.getInputs().get(inputName);
+        final EntrySchema entrySchema = layerProtocolsInput.getEntry_schema();
+        entrySchema.setType(IP_REQUIREMENTS_TYPE);
+        final List<String> defaultLayerProtocolList = (List<String>) layerProtocolsInput.get_default();
+        layerProtocolsInput.set_default(convertToIpRequirementsProperty(defaultLayerProtocolList));
+    }
+
+    /**
+     * Converts each layer_protocols entry that is either {@link #IP_V4} or {@link #IP_V6} to the ecomp
+     * {@link #IP_REQUIREMENTS_TYPE}, ignoring other entry types.
+     *
+     * @param layerProtocols    the PnfExtCp layer_protocols list
+     * @return
+     *  A list of map representing a {@link #IP_REQUIREMENTS_TYPE} ecomp type
+     */
+    private List<Map<String, Object>> convertToIpRequirementsProperty(final List<String> layerProtocols) {
         return layerProtocols.stream()
-                .filter(layerProtocol -> IP_V4.equals(layerProtocol) || IP_V6.equals(layerProtocol))
-                .map(this::createIpPropertyElement)
-                .collect(Collectors.toList());
+            .filter(layerProtocol -> IP_V4.equals(layerProtocol) || IP_V6.equals(layerProtocol))
+            .map(this::createIpRequirementsEntry)
+            .collect(Collectors.toList());
     }
 
-    private Map<String, Object> createIpPropertyElement(String ipVersion) {
-        final int version = ipVersion.equals(IP_V4) ? 4 : 6;
-        Map<String, Object> result = new HashMap<>();
+    /**
+     * Creates a {@link #IP_REQUIREMENTS_TYPE} based on the ip version
+     * @param ipVersion  the provided ip version, either {@link #IP_V4} or {@link #IP_V6}
+     * @return
+     *  A map representing an {@link #IP_REQUIREMENTS_TYPE} ecomp type
+     */
+    private Map<String, Object> createIpRequirementsEntry(final String ipVersion) {
+        final int version = IP_V4.equals(ipVersion) ? 4 : 6;
+        final Map<String, Object> result = new HashMap<>();
         result.put(IP_VERSION, version);
         result.put(ASSIGNMENT_METHOD, DHCP);
         return result;
     }
 
-    private boolean isNotEmpty(List<?> list) {
-        return !list.isEmpty();
-    }
-
-    private void addEmptyNodeTemplatesIfNoneDefined(ServiceTemplate serviceTemplate) {
+    /**
+     * Fills missing required entries in the service template. Checks for topology_template entry and
+     * topology_template->node_templates entry.
+     */
+    private void addEmptyNodeTemplatesIfNoneDefined() {
         TopologyTemplate topologyTemplate = serviceTemplate.getTopology_template();
         if (Objects.isNull(topologyTemplate)) {
             topologyTemplate = new TopologyTemplate();
@@ -144,4 +254,18 @@ public class ToscaSolConverterPnf extends AbstractToscaSolConverter {
         }
     }
 
+    /**
+     * Parses an input entry schema
+     *
+     * @param entrySchemaMap    the descriptor input entry schema map
+     * @return
+     *  A parsed entry schema based on the provided map
+     */
+    private EntrySchema parseEntrySchema(Map entrySchemaMap) {
+        return DataModelUtil.createEntrySchema((String) entrySchemaMap.get(TYPE.getElementName())
+            , (String) entrySchemaMap.get(DESCRIPTION.getElementName())
+            , (List<Constraint>) entrySchemaMap.get(CONSTRAINTS.getElementName())
+        );
+    }
+
 }
\ No newline at end of file
index c3f38fe..4d59d6b 100644 (file)
 
 package org.openecomp.core.impl;
 
-import org.apache.commons.io.IOUtils;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
-import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
-import org.onap.sdc.tosca.services.YamlUtil;
-import org.openecomp.core.converter.ServiceTemplateReaderService;
-import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.equalTo;
+import static org.junit.Assert.fail;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -40,14 +34,21 @@ import java.nio.file.Paths;
 import java.util.Collection;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
-
-import static org.junit.Assert.assertEquals;
+import org.apache.commons.io.IOUtils;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.onap.sdc.tosca.datatypes.model.ServiceTemplate;
+import org.onap.sdc.tosca.services.ToscaExtensionYamlUtil;
+import org.onap.sdc.tosca.services.YamlUtil;
+import org.openecomp.core.converter.ServiceTemplateReaderService;
+import org.openecomp.core.impl.services.ServiceTemplateReaderServiceImpl;
 
 @RunWith(Parameterized.class)
 public class ToscaSolConverterPnfTest {
 
-    public static final String INPUT_DIR = "pnfDescriptor/in/";
-    public static final String OUTPUT_DIR = "pnfDescriptor/out/";
+    private static final String INPUT_DIR = "pnfDescriptor/in/";
+    private static final String OUTPUT_DIR = "pnfDescriptor/out/";
     private String inputFilename;
     private YamlUtil yamlUtil = new YamlUtil();
     private ToscaExtensionYamlUtil toscaExtensionYamlUtil = new ToscaExtensionYamlUtil();
@@ -65,49 +66,59 @@ public class ToscaSolConverterPnfTest {
     }
 
     @Test
-    public void testTopologyTemplateConversions() throws IOException {
+    public void testTopologyTemplateConversions() {
         final byte[] descriptor = getInputFileResource(inputFilename);
-        ServiceTemplateReaderService serviceTemplateReaderService = new ServiceTemplateReaderServiceImpl(descriptor);
-        ServiceTemplate serviceTemplate = new ServiceTemplate();
-        ToscaSolConverterPnf toscaSolConverter = new ToscaSolConverterPnf();
+        final ServiceTemplateReaderService serviceTemplateReaderService =
+            new ServiceTemplateReaderServiceImpl(descriptor);
+        final ServiceTemplate serviceTemplate = new ServiceTemplate();
+        final ToscaSolConverterPnf toscaSolConverter = new ToscaSolConverterPnf();
         toscaSolConverter.convertTopologyTemplate(serviceTemplate, serviceTemplateReaderService);
 
-        String result = yamlUtil.objectToYaml(serviceTemplate);
-        String expectedResult = getExpectedResultFor(inputFilename);
-        assertEquals(expectedResult, result);
+        final String actualYaml = yamlUtil.objectToYaml(serviceTemplate);
+        final String expectedYaml = getExpectedResultFor(inputFilename);
+        assertThat("Converted PNF descriptor should be the same as the expected topology template", actualYaml,
+            equalTo(expectedYaml));
     }
 
-    private String getExpectedResultFor(String inputFilename) throws IOException {
-        try (InputStream inputStream = getOutputFileResourceCorrespondingTo(inputFilename)) {
-            ServiceTemplate serviceTemplate = toscaExtensionYamlUtil.yamlToObject(inputStream, ServiceTemplate.class);
+    private String getExpectedResultFor(final String inputFilename)  {
+        try (final InputStream inputStream = getOutputFileResourceCorrespondingTo(inputFilename)) {
+            final ServiceTemplate serviceTemplate = toscaExtensionYamlUtil.yamlToObject(inputStream, ServiceTemplate.class);
             return yamlUtil.objectToYaml(serviceTemplate);
+        } catch (final IOException e) {
+            fail(String.format("Could not find file '%s'", inputFilename));
         }
+
+        return null;
     }
 
-    private static Path getPathFromClasspath(String location) {
+    private static Path getPathFromClasspath(final String location) {
         return Paths.get(Thread.currentThread().getContextClassLoader().getResource(location).getPath());
     }
 
-    private byte[] getInputFileResource(String inputFilename) throws IOException {
+    private byte[] getInputFileResource(final String inputFilename) {
         return getFileResource(INPUT_DIR + inputFilename);
     }
 
-    private InputStream getOutputFileResourceCorrespondingTo(String inputFilename) {
-        String outputFilename = getOutputFilenameFrom(inputFilename);
+    private InputStream getOutputFileResourceCorrespondingTo(final String inputFilename) {
+        final String outputFilename = getOutputFilenameFrom(inputFilename);
         return getFileResourceAsInputStream(OUTPUT_DIR + outputFilename);
     }
 
-    private String getOutputFilenameFrom(String inputFilename) {
+    private String getOutputFilenameFrom(final String inputFilename) {
         return inputFilename.replace("pnfDescriptor", "topologyTemplate");
     }
 
-    private byte[] getFileResource(String filePath) throws IOException {
+    private byte[] getFileResource(final String filePath) {
         try (InputStream inputStream = getFileResourceAsInputStream(filePath)) {
             return IOUtils.toByteArray(inputStream);
+        } catch (final IOException e) {
+            fail(String.format("Could not find file '%s'", filePath));
         }
+
+        return null;
     }
 
-    private InputStream getFileResourceAsInputStream(String filePath) {
+    private InputStream getFileResourceAsInputStream(final String filePath) {
         return Thread.currentThread().getContextClassLoader().getResourceAsStream(filePath);
     }
 
diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsAndDuplicatedGetInput.yaml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsAndDuplicatedGetInput.yaml
new file mode 100644 (file)
index 0000000..8549da0
--- /dev/null
@@ -0,0 +1,45 @@
+tosca_definitions_version: tosca_simple_yaml_1_2
+
+description: service template of an Acme PNF
+
+imports:
+  - etsi_nfv_sol001_pnfd_2_5_1_types.yaml
+
+topology_template:
+  inputs:
+    protocols:
+      type: list
+      description: IP protocols
+      entry_schema:
+        type: string
+      default: [ ipv4, ipv6 ]
+  node_templates:
+    myPnf:
+      type: tosca.nodes.nfv.PNF
+      properties:
+        descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a2233
+        function_description: Acme PNF
+        provider: Acme
+        version: 1.0
+        descriptor_invariant_id: 1111-2222-ccaa-bbdd
+        name: Acme PNF
+
+    pnfExtCp_1:
+      type: tosca.nodes.nfv.PnfExtCp
+      properties:
+        trunk_mode: false
+        layer_protocols: { get_input: protocols }
+        role: leaf
+        description: External connection point to access Acme myPnf
+      requirements:
+        - dependency: myPnf
+
+    pnfExtCp_2:
+      type: tosca.nodes.nfv.PnfExtCp
+      properties:
+        trunk_mode: false
+        layer_protocols: { get_input: protocols }
+        role: leaf
+        description: External connection point to access Acme myPnf
+      requirements:
+        - dependency: myPnf
diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsGetInput.yaml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsGetInput.yaml
new file mode 100644 (file)
index 0000000..bb4dd9c
--- /dev/null
@@ -0,0 +1,39 @@
+tosca_definitions_version: tosca_simple_yaml_1_2
+
+description: service template of an Acme PNF
+
+imports:
+  - etsi_nfv_sol001_pnfd_2_5_1_types.yaml
+
+topology_template:
+  inputs:
+    anyOtherInput:
+      type: string
+      description: this is input1
+      default: defaultValue
+    protocols:
+      type: list
+      description: IP protocols
+      entry_schema:
+        type: string
+      default: [ ipv4, ipv6 ]
+  node_templates:
+    myPnf:
+      type: tosca.nodes.nfv.PNF
+      properties:
+        descriptor_id: b1bb0ce7-ebca-4fa7-95ed-4840d70a2233
+        function_description: Acme PNF
+        provider: Acme
+        version: 1.0
+        descriptor_invariant_id: 1111-2222-ccaa-bbdd
+        name: Acme PNF
+
+    pnfExtCp_1:
+      type: tosca.nodes.nfv.PnfExtCp
+      properties:
+        trunk_mode: false
+        layer_protocols: { get_input: protocols }
+        role: leaf
+        description: External connection point to access Acme myPnf
+      requirements:
+        - dependency: myPnf
index 26255dd..b373344 100644 (file)
@@ -3,6 +3,17 @@ tosca_definitions_version: tosca_simple_yaml_1_1
 description: service template of a PNF
 
 topology_template:
+  inputs:
+    role:
+      type: string
+      description: Role
+      default: leaf
+    layer_protocols:
+      type: list
+      description: IP protocols
+      entry_schema:
+        type: string
+      default: [ipv4, ipv6, otherProtocol]
   node_templates:
     pnf_mainPart:
       type: tosca.nodes.nfv.PNF
@@ -28,6 +39,6 @@ topology_template:
       type: tosca.nodes.nfv.PnfExtCp
       properties:
         trunk_mode: false
-        layer_protocols: [ ipv4, ipv6, otherProtocol ]
-        role: leaf
+        layer_protocols: {get_input: layer_protocols}
+        role: {get_input: role}
         description: External connection point to access this pnf
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsAndDuplicatedGetInput.yaml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsAndDuplicatedGetInput.yaml
new file mode 100644 (file)
index 0000000..637ccd3
--- /dev/null
@@ -0,0 +1,17 @@
+topology_template:
+  inputs:
+    protocols:
+      type: list
+      description: IP protocols
+      entry_schema:
+        type: org.openecomp.datatypes.network.IpRequirements
+      default: [{assingment_method: dhcp, ip_version: 4}, {assingment_method: dhcp, ip_version: 6}]
+  node_templates:
+    pnfExtCp_2:
+      type: org.openecomp.resource.cp.v2.extCP
+      properties:
+        ip_requirements: { get_input: protocols }
+    pnfExtCp_1:
+      type: org.openecomp.resource.cp.v2.extCP
+      properties:
+        ip_requirements: { get_input: protocols }
\ No newline at end of file
diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsGetInput.yaml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsGetInput.yaml
new file mode 100644 (file)
index 0000000..ca1a236
--- /dev/null
@@ -0,0 +1,13 @@
+topology_template:
+  inputs:
+    protocols:
+      type: list
+      description: IP protocols
+      entry_schema:
+        type: org.openecomp.datatypes.network.IpRequirements
+      default: [{assingment_method: dhcp, ip_version: 4}, {assingment_method: dhcp, ip_version: 6}]
+  node_templates:
+    pnfExtCp_1:
+      type: org.openecomp.resource.cp.v2.extCP
+      properties:
+        ip_requirements: { get_input: protocols }
\ No newline at end of file
index 2fc10d2..5ec67f1 100644 (file)
@@ -528,7 +528,7 @@ public class DataModelUtil {
      * @param defaultVal  the default val
      * @return the property definition
      */
-    public static ParameterDefinition createParameterDefinition(String type, String description, boolean required,
+    public static ParameterDefinition createParameterDefinition(String type, String description, Boolean required,
                                                                 List<Constraint> constraints, EntrySchema entrySchema,
                                                                 Object defaultVal) {
         ParameterDefinition paramDef = new ParameterDefinition();