diff options
11 files changed, 374 insertions, 110 deletions
diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java index a764c89db2..b1356fc11b 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java @@ -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() { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java index 5355ad95df..c40c845718 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -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()) { diff --git a/common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java b/common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java index 6f2cc9c7cc..408fb5042a 100644 --- a/common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java +++ b/common-be/src/main/java/org/openecomp/sdc/be/utils/TypeUtils.java @@ -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; } diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/ToscaSolConverterPnf.java b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/ToscaSolConverterPnf.java index 0258b42a3d..a3935ee735 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/ToscaSolConverterPnf.java +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/main/java/org/openecomp/core/impl/ToscaSolConverterPnf.java @@ -22,118 +22,228 @@ 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 diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/java/org/openecomp/core/impl/ToscaSolConverterPnfTest.java b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/java/org/openecomp/core/impl/ToscaSolConverterPnfTest.java index c3f38fe3cd..4d59d6bfe9 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/java/org/openecomp/core/impl/ToscaSolConverterPnfTest.java +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/java/org/openecomp/core/impl/ToscaSolConverterPnfTest.java @@ -22,15 +22,9 @@ 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 index 0000000000..8549da09b2 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsAndDuplicatedGetInput.yaml @@ -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 index 0000000000..bb4dd9c87b --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/in/pnfDescriptor_withLayerProtocolsGetInput.yaml @@ -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 diff --git a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/other/pnfDescriptor_PnfAnd2ExtCps.yaml b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/other/pnfDescriptor_PnfAnd2ExtCps.yaml index 26255ddd84..b37334496c 100644 --- a/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/other/pnfDescriptor_PnfAnd2ExtCps.yaml +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/other/pnfDescriptor_PnfAnd2ExtCps.yaml @@ -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 index 0000000000..637ccd3eae --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsAndDuplicatedGetInput.yaml @@ -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 index 0000000000..ca1a236101 --- /dev/null +++ b/openecomp-be/lib/openecomp-tosca-converter-lib/openecomp-tosca-converter-core/src/test/resources/pnfDescriptor/out/topologyTemplate_withLayerProtocolsGetInput.yaml @@ -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 diff --git a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java index 2fc10d2d2b..5ec67f11db 100644 --- a/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java +++ b/openecomp-be/lib/openecomp-tosca-lib/src/main/java/org/openecomp/sdc/tosca/services/DataModelUtil.java @@ -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(); |