From 7cd3f6bbd4524421f290aa6b5f89836bc98c8cbf Mon Sep 17 00:00:00 2001 From: MichaelMorris Date: Wed, 27 May 2020 18:09:40 +0100 Subject: Importing VSP with node_type in separate file Import fails when a node_type referenced in the main template is defined in a separate yaml file in the csar even when that separate file is correctly imported in the main template Change-Id: I6abe074585c2ce592fe9bed7abe76f0856bcfe93 Issue-ID: SDC-2850 Signed-off-by: MichaelMorris --- .../openecomp/sdc/be/components/csar/CsarInfo.java | 76 ++++++++++++++++++++- .../be/components/impl/ResourceBusinessLogic.java | 3 +- .../sdc/be/components/csar/CsarInfoTest.java | 14 +++- .../src/test/resources/nodeTypeInGlobalSub.csar | Bin 0 -> 2442 bytes 4 files changed, 88 insertions(+), 5 deletions(-) create mode 100644 catalog-be/src/test/resources/nodeTypeInGlobalSub.csar (limited to 'catalog-be') diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java index 58beecbf20..feb18c22e6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java @@ -45,6 +45,7 @@ import org.yaml.snakeyaml.Yaml; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; @@ -133,11 +134,13 @@ public class CsarInfo { public Map extractNodeTypesInfo() { Map nodeTypesInfo = new HashMap<>(); List> globalSubstitutes = new ArrayList<>(); + final Set nodeTypesUsedInNodeTemplates = new HashSet<>(); for (Map.Entry entry : getCsar().entrySet()) { - extractNodeTypeInfo(nodeTypesInfo, globalSubstitutes, entry); + extractNodeTypeInfo(nodeTypesInfo, globalSubstitutes, nodeTypesUsedInNodeTemplates, entry); } if (CollectionUtils.isNotEmpty(globalSubstitutes)) { setDerivedFrom(nodeTypesInfo, globalSubstitutes); + addGlobalSubstitutionsToNodeTypes(globalSubstitutes, nodeTypesUsedInNodeTemplates, nodeTypesInfo); } markNestedVfc(getMappedToscaMainTemplate(), nodeTypesInfo); return nodeTypesInfo; @@ -145,7 +148,7 @@ public class CsarInfo { @SuppressWarnings("unchecked") private void extractNodeTypeInfo(Map nodeTypesInfo, - List> globalSubstitutes, Map.Entry entry) { + List> globalSubstitutes, final Set nodeTypesUsedInNodeTemplates, Map.Entry entry) { if (isAServiceTemplate(entry.getKey())) { if (isGlobalSubstitute(entry.getKey())) { globalSubstitutes.add(entry); @@ -154,13 +157,28 @@ public class CsarInfo { findToscaElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.SUBSTITUTION_MAPPINGS, ToscaElementTypeEnum.MAP) .right() .on(sub->handleSubstitutionMappings(nodeTypesInfo, entry, mappedToscaTemplate, (Map)sub)); + + final Either nodeTypesEither = findToscaElement(mappedToscaTemplate, + TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + final Map> nodeTemplates = (Map>) nodeTypesEither.left().value(); + nodeTypesUsedInNodeTemplates.addAll(findNodeTypesUsedInNodeTemplates(nodeTemplates)); + } } } } private boolean isAServiceTemplate(final String filePath) { return Pattern.compile(CsarUtils.SERVICE_TEMPLATE_PATH_PATTERN).matcher(filePath).matches(); - } + } + + private Set findNodeTypesUsedInNodeTemplates(final Map> nodeTemplates) { + final Set nodeTypes = new HashSet<>(); + for (final Map nodeTemplate : nodeTemplates.values()) { + nodeTypes.add((String)nodeTemplate.get(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())); + } + return nodeTypes; + } private ResultStatusEnum handleSubstitutionMappings(Map nodeTypesInfo, Map.Entry entry, Map mappedToscaTemplate, Map substitutionMappings) { final Set nodeTypesDefinedInTemplate = findNodeTypesDefinedInTemplate(mappedToscaTemplate); @@ -227,12 +245,64 @@ public class CsarInfo { .right() .on(nts-> processNodeTemplates((Map)nts, nodeTypesInfo)); } + + @SuppressWarnings("unchecked") + private void addGlobalSubstitutionsToNodeTypes(final List> globalSubstitutes, final Set nodeTypesUsedInNodeTemplates, final Map nodeTypesInfo) { + for (Map.Entry entry : globalSubstitutes) { + final String yamlFileContents = new String(entry.getValue()); + final Map mappedToscaTemplate = (Map) new Yaml().load(yamlFileContents); + final Either nodeTypesEither = findToscaElement(mappedToscaTemplate, + TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP); + if (nodeTypesEither.isLeft()) { + final Map nodeTypes = (Map) nodeTypesEither.left().value(); + for (final Map.Entry nodeType : nodeTypes.entrySet()) { + + if (!nodeTypesInfo.containsKey(nodeType.getKey()) && nodeTypesUsedInNodeTemplates.contains(nodeType.getKey())) { + nodeTypesInfo.put(nodeType.getKey(), buildNodeTypeInfo(nodeType, entry.getKey(), mappedToscaTemplate)); + } + } + } + } + } @SuppressWarnings("unchecked") private static ResultStatusEnum processNodeTemplates( Map nodeTemplates, Map nodeTypesInfo) { nodeTemplates.values().forEach(nt->processNodeTemplate(nodeTypesInfo, (Map) nt)); return ResultStatusEnum.OK; } + + @SuppressWarnings("unchecked") + private NodeTypeInfo buildNodeTypeInfo(final Map.Entry nodeType, final String templateFileName, final Map mappedToscaTemplate ) { + final NodeTypeInfo nodeTypeInfo = new NodeTypeInfo(); + nodeTypeInfo.setSubstitutionMapping(false); + nodeTypeInfo.setNested(true); + nodeTypeInfo.setType(nodeType.getKey()); + nodeTypeInfo.setTemplateFileName(templateFileName); + nodeTypeInfo.setMappedToscaTemplate(buildToscaTemplateForNode(nodeType.getKey(), mappedToscaTemplate)); + + final Map nodeTypeMap = (Map) nodeType.getValue(); + final List derivedFrom = new ArrayList<>(); + derivedFrom.add((String) nodeTypeMap.get(TypeUtils.ToscaTagNamesEnum.DERIVED_FROM.getElementName())); + nodeTypeInfo.setDerivedFrom(derivedFrom); + + return nodeTypeInfo; + } + + @SuppressWarnings("unchecked") + private Map buildToscaTemplateForNode(final String nodeTypeName, final Map mappedToscaTemplate) { + final Map mappedToscaTemplateforNode = new HashMap<>(mappedToscaTemplate); + + final Either nodeTypesEither = findToscaElement(mappedToscaTemplate, + TypeUtils.ToscaTagNamesEnum.NODE_TYPES, ToscaElementTypeEnum.MAP); + final Map nodeTypes = new HashMap<>(); + if (nodeTypesEither.isLeft()) { + final Map allNodeTypes = (Map) nodeTypesEither.left().value(); + nodeTypes.put(nodeTypeName, allNodeTypes.get(nodeTypeName)); + } + + mappedToscaTemplateforNode.put(TypeUtils.ToscaTagNamesEnum.NODE_TYPES.getElementName(), nodeTypes); + return mappedToscaTemplateforNode; + } private static void processNodeTemplate(Map nodeTypesInfo, Map nodeTemplate) { if (nodeTemplate.containsKey(TypeUtils.ToscaTagNamesEnum.TYPE.getElementName())) { 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 7eda330fe3..f479bb5c0f 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 @@ -36,6 +36,7 @@ import com.google.common.annotations.VisibleForTesting; import fj.data.Either; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.EnumMap; import java.util.HashMap; import java.util.HashSet; @@ -1296,7 +1297,7 @@ public class ResourceBusinessLogic extends ComponentBusinessLogic { log.debug("************* Going to create node types from yaml {}", yamlName); createResourcesFromYamlNodeTypesList(yamlName, resource, nestedVfcJsonMap, false, nodesArtifactsToHandle, - createdArtifacts, nodesInfo, csarInfo); + createdArtifacts, Collections.emptyMap(), csarInfo); log.debug("************* Finished to create node types from yaml {}", yamlName); if (nestedVfcJsonMap.containsKey(TypeUtils.ToscaTagNamesEnum.TOPOLOGY_TEMPLATE.getElementName())) { diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java index a28e2efcdb..f3f0ab5628 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/csar/CsarInfoTest.java @@ -38,7 +38,7 @@ import org.openecomp.sdc.common.impl.ExternalConfiguration; import org.openecomp.sdc.common.impl.FSConfigurationSource; import org.openecomp.sdc.common.zip.ZipUtils; import org.openecomp.sdc.common.zip.exception.ZipException; - +import com.datastax.oss.driver.shaded.guava.common.collect.Lists; import java.io.File; import java.net.URISyntaxException; import java.util.Arrays; @@ -167,4 +167,16 @@ public class CsarInfoTest { assertTrue(csarInfo.extractNodeTypesInfo().isEmpty()); } + + @Test + public void testCreateCsarInfoVnfWithNodeTypeInGlobalSub() throws URISyntaxException, ZipException { + final CsarInfo csarInfo = createCsarInfo("nodeTypeInGlobalSub.csar", "Definitions/MainServiceTemplate.yaml"); + + assertEquals(1, csarInfo.extractNodeTypesInfo().size()); + final NodeTypeInfo nodeTypeInfo = csarInfo.extractNodeTypesInfo().get("tosca.nodes.l3vpn"); + assertNotNull(nodeTypeInfo); + assertEquals("Definitions/GlobalSubstitutionTypesServiceTemplate.yaml", nodeTypeInfo.getTemplateFileName()); + assertEquals("tosca.nodes.l3vpn", nodeTypeInfo.getType()); + assertEquals(Lists.newArrayList("tosca.nodes.Root"), nodeTypeInfo.getDerivedFrom()); + } } diff --git a/catalog-be/src/test/resources/nodeTypeInGlobalSub.csar b/catalog-be/src/test/resources/nodeTypeInGlobalSub.csar new file mode 100644 index 0000000000..67ada85000 Binary files /dev/null and b/catalog-be/src/test/resources/nodeTypeInGlobalSub.csar differ -- cgit 1.2.3-korg