From c2ead8ac02672ab9af997272e211b0f0992288a1 Mon Sep 17 00:00:00 2001 From: JvD_Ericsson Date: Fri, 22 Jul 2022 10:25:52 +0100 Subject: Service import - Import unknown node types Issue-ID: SDC-4118 Signed-off-by: JvD_Ericsson Change-Id: Id620eef55ffb6849006e8a7bc063709150628e76 --- .../openecomp/sdc/be/components/csar/CsarInfo.java | 16 ++ .../sdc/be/components/csar/ServiceCsarInfo.java | 198 +++++++++++++++++++-- .../be/components/impl/ResourceImportManager.java | 8 +- .../impl/ServiceImportBusinessLogic.java | 49 ++++- .../be/components/ResourceImportManagerTest.java | 60 +++++++ .../impl/ServiceImportBusinessLogicTest.java | 3 + .../csars/service-Etsiwithchild-csar.csar | Bin 0 -> 50857 bytes .../openecomp/sdc/be/model/NodeTypeDefinition.java | 14 ++ 8 files changed, 322 insertions(+), 26 deletions(-) create mode 100644 catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csar create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java 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 49b7bb2f86..0bc6224273 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 @@ -26,6 +26,7 @@ import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; 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.HashMap; import java.util.HashSet; @@ -35,6 +36,7 @@ import java.util.Optional; import java.util.PriorityQueue; import java.util.Queue; import java.util.Set; +import java.util.stream.Stream; import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.MapUtils; @@ -194,6 +196,20 @@ public abstract class CsarInfo { return Collections.emptyMap(); } + @SuppressWarnings("unchecked") + protected Map getTypesFromTemplate(final Map mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type, Collection names) { + Map allTypes = getTypesFromTemplate(mappedToscaTemplate, type); + + final Map typesToReturn = new HashMap<>(); + final Stream> requestedTypes = allTypes.entrySet().stream().filter(entry -> names.contains(entry.getKey())); + + requestedTypes.forEach(requestedType -> { + typesToReturn.put(requestedType.getKey(), requestedType.getValue()); + }); + + return typesToReturn; + } + protected Set findNodeTypesUsedInNodeTemplates(final Map> nodeTemplates) { final Set nodeTypes = new HashSet<>(); for (final Map nodeTemplate : nodeTemplates.values()) { diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java index ca3c92bcbd..8dfe106713 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java @@ -21,7 +21,10 @@ package org.openecomp.sdc.be.components.csar; +import static org.openecomp.sdc.be.components.impl.ImportUtils.Constants.DEFAULT_ICON; import static org.openecomp.sdc.be.components.impl.ImportUtils.findToscaElement; + +import fj.data.Either; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -31,28 +34,35 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.NodeTypeDefinition; import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.NodeTypeMetadata; import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.be.utils.TypeUtils.ToscaTagNamesEnum; import org.openecomp.sdc.common.log.wrappers.Logger; import org.yaml.snakeyaml.Yaml; -import fj.data.Either; /** * Provides access to the contents of a Service CSAR */ public class ServiceCsarInfo extends CsarInfo { - private Map> mainTemplateImports; private static final Logger log = Logger.getLogger(ServiceCsarInfo.class); + private final Map> mainTemplateImports; + private List nodeTypeDefinitions; public ServiceCsarInfo(final User modifier, final String csarUUID, final Map csar, final String vfResourceName, - final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { + final String mainTemplateName, final String mainTemplateContent, final boolean isUpdate) { super(modifier, csarUUID, csar, vfResourceName, mainTemplateName, mainTemplateContent, isUpdate); final Path mainTemplateDir = Paths.get(getMainTemplateName().substring(0, getMainTemplateName().lastIndexOf('/') + 1)); @@ -60,12 +70,12 @@ public class ServiceCsarInfo extends CsarInfo { filesHandled.add(Paths.get(mainTemplateName)); this.mainTemplateImports = getTemplateImports(csar, new Yaml().load(mainTemplateContent), mainTemplateDir, filesHandled); } - + private Map> getTemplateImports(final Map csar, Map mappedToscaMainTemplate, - final Path fileParentDir, final Collection filesHandled) { + final Path fileParentDir, final Collection filesHandled) { final Map> templateImports = new HashMap<>(); - final List importFilePaths = getTempateImportFilePaths(mappedToscaMainTemplate, fileParentDir); + final List importFilePaths = getTemplateImportFilePaths(mappedToscaMainTemplate, fileParentDir); importFilePaths.stream().filter(path -> !filesHandled.contains(path)).forEach( importFilePath -> { @@ -74,9 +84,7 @@ public class ServiceCsarInfo extends CsarInfo { filesHandled.add(importFilePath); Map mappedImportFile = new Yaml().load(new String(csar.get(importFilePath.toString()))); templateImports.put(importFilePath.toString(), mappedImportFile); - templateImports.putAll(getTemplateImports(csar, mappedImportFile, importFilePath.getParent(), filesHandled)); - } else { log.info("Import {} cannot be found in CSAR", importFilePath.toString()); } @@ -84,18 +92,18 @@ public class ServiceCsarInfo extends CsarInfo { return templateImports; } - + @SuppressWarnings({"unchecked", "rawtypes"}) - private List getTempateImportFilePaths(final Map mappedToscaTemplate, final Path fileParentDir) { + private List getTemplateImportFilePaths(final Map mappedToscaTemplate, final Path fileParentDir) { final Either importsEither = - findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.IMPORTS, ToscaElementTypeEnum.ALL); + findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.IMPORTS, ToscaElementTypeEnum.ALL); if (importsEither.isLeft()) { final List importsList = (List) importsEither.left().value(); if (CollectionUtils.isNotEmpty(importsList)) { if (importsList.get(0) instanceof String) { List importPaths = new ArrayList<>(); - importsList.stream().forEach(importPath -> importPaths.add(Paths.get((String)importPath))); + importsList.stream().forEach(importPath -> importPaths.add(Paths.get((String) importPath))); return importPaths; } else if (importsList.get(0) instanceof Map) { return getTemplateImportFilePathsMultiLineGrammar(importsList, fileParentDir); @@ -110,11 +118,11 @@ public class ServiceCsarInfo extends CsarInfo { private List getTemplateImportFilePathsMultiLineGrammar(final List> importsList, final Path fileParentDir) { final List importFiles = new ArrayList<>(); - for (Map importFileMultiLineGrammar : (List>) importsList) { + for (Map importFileMultiLineGrammar : importsList) { if (MapUtils.isNotEmpty(importFileMultiLineGrammar)) { if (importFileMultiLineGrammar.values().iterator().next() instanceof String) { Path relativePath = Paths.get((String) importFileMultiLineGrammar.get("file")); - Path absolutePath = fileParentDir.resolve(relativePath).normalize(); + Path absolutePath = fileParentDir == null ? relativePath : fileParentDir.resolve(relativePath).normalize(); importFiles.add(absolutePath); } else if (importFileMultiLineGrammar.values().iterator().next() instanceof Map) { importFileMultiLineGrammar.values().forEach(value -> { @@ -137,9 +145,169 @@ public class ServiceCsarInfo extends CsarInfo { public Map getDataTypes() { final Map definitions = new HashMap<>(); mainTemplateImports.entrySet().stream() - .forEach(entry -> definitions.putAll(getTypesFromTemplate(entry.getValue(), TypeUtils.ToscaTagNamesEnum.DATA_TYPES))); + .forEach(entry -> definitions.putAll(getTypesFromTemplate(entry.getValue(), TypeUtils.ToscaTagNamesEnum.DATA_TYPES))); definitions.putAll(getTypesFromTemplate(getMappedToscaMainTemplate(), TypeUtils.ToscaTagNamesEnum.DATA_TYPES)); return definitions; } + public List getNodeTypesUsed() { + if (nodeTypeDefinitions == null) { + nodeTypeDefinitions = new ArrayList<>(); + final Set nodeTypesUsed = getNodeTypesUsedInToscaTemplate(getMappedToscaMainTemplate()); + nodeTypeDefinitions.addAll(getNodeTypeDefinitions(nodeTypesUsed)); + } + nodeTypeDefinitions = sortNodeTypesByDependencyOrder(nodeTypeDefinitions); + return nodeTypeDefinitions; + } + + private List sortNodeTypesByDependencyOrder(final List nodeTypes) { + final List sortedNodeTypeDefinitions = new ArrayList<>(); + final Map nodeTypeDefinitionsMap = new HashMap<>(); + + nodeTypes.forEach(nodeType -> { + int highestDependencyIndex = -1; + for (final String dependencyName : getDependencyTypes(nodeType, nodeTypes)) { + final NodeTypeDefinition dependency = nodeTypeDefinitionsMap.get(dependencyName); + final int indexOfDependency = sortedNodeTypeDefinitions.lastIndexOf(dependency); + highestDependencyIndex = indexOfDependency > highestDependencyIndex ? indexOfDependency : highestDependencyIndex; + } + sortedNodeTypeDefinitions.add(highestDependencyIndex + 1, nodeType); + nodeTypeDefinitionsMap.put(nodeType.getNodeTypeMetadata().getToscaName(), nodeType); + }); + return sortedNodeTypeDefinitions; + } + + private Collection getDependencyTypes(final NodeTypeDefinition nodeType, final List nodeTypes) { + final Set dependencies = new HashSet<>(); + Either derivedFromTypeEither = findToscaElement((Map) nodeType.getMappedNodeType().getValue(), + TypeUtils.ToscaTagNamesEnum.DERIVED_FROM, ToscaElementTypeEnum.STRING); + if (derivedFromTypeEither.isLeft() && derivedFromTypeEither.left().value() != null) { + final String derivedFrom = (String) derivedFromTypeEither.left().value(); + dependencies.add(derivedFrom); + nodeTypes.stream().filter(derivedFromCandidate -> derivedFrom.contentEquals(derivedFromCandidate.getNodeTypeMetadata().getToscaName())) + .forEach(derivedFromNodeType -> dependencies.addAll(getDependencyTypes(derivedFromNodeType, nodeTypes))); + } + return dependencies; + } + + private Set getNodeTypeDefinitions(final Set nodeTypesToGet) { + final Set nodeTypesToReturn = new HashSet<>(); + final Set foundNodeTypes = getTypes(nodeTypesToGet); + nodeTypesToReturn.addAll(foundNodeTypes); + final Set recursiveNodeTypesToGet = new HashSet<>(); + foundNodeTypes.stream().forEach(nodeTypeDef -> { + Either derivedFromTypeEither = + findToscaElement((Map) nodeTypeDef.getMappedNodeType().getValue(), TypeUtils.ToscaTagNamesEnum.DERIVED_FROM, + ToscaElementTypeEnum.STRING); + if (derivedFromTypeEither.isLeft()) { + recursiveNodeTypesToGet.add((String)derivedFromTypeEither.left().value()); + } + }); + recursiveNodeTypesToGet.removeAll(nodeTypesToGet); + if (CollectionUtils.isNotEmpty(recursiveNodeTypesToGet)) { + nodeTypesToReturn.addAll(getNodeTypeDefinitions(recursiveNodeTypesToGet)); + } + return nodeTypesToReturn; + } + + + private Set getTypes(final Set nodeTypes) { + Set nodeTypeDefinitionsLocal = new HashSet<>(); + mainTemplateImports.entrySet().forEach(entry -> { + final Map types = getTypesFromTemplate(entry.getValue(), TypeUtils.ToscaTagNamesEnum.NODE_TYPES, nodeTypes); + if (MapUtils.isNotEmpty(types)) { + types.entrySet().stream().forEach(typesEntry -> { + final NodeTypeMetadata metadata = + getMetaDataFromTemplate(entry.getValue(), typesEntry.getKey()); + nodeTypeDefinitionsLocal.add(new NodeTypeDefinition(typesEntry, metadata)); + }); + } + }); + return nodeTypeDefinitionsLocal; + } + + @SuppressWarnings("unchecked") + private Set getNodeTypesUsedInToscaTemplate(Map mappedToscaTemplate) { + final Either nodeTemplatesEither = findToscaElement(mappedToscaTemplate, + TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP); + final Set nodeTypesUsedInNodeTemplates = new HashSet<>(); + if (nodeTemplatesEither.isLeft()) { + final Map> nodeTemplates = + (Map>) nodeTemplatesEither.left().value(); + nodeTypesUsedInNodeTemplates.addAll(findNodeTypesUsedInNodeTemplates(nodeTemplates)); + } + return nodeTypesUsedInNodeTemplates; + } + + private NodeTypeMetadata getMetaDataFromTemplate(Map mappedResourceTemplate, String nodeTemplateType) { + NodeTypeMetadata nodeTypeMetadata = new NodeTypeMetadata(); + Either, ImportUtils.ResultStatusEnum> metadataEither = ImportUtils.findFirstToscaMapElement(mappedResourceTemplate, TypeUtils.ToscaTagNamesEnum.METADATA); + if (metadataEither.isLeft() && metadataEither.left().value().get("type").equals(ResourceTypeEnum.VFC.getValue())) { + Map metadata = metadataEither.left().value(); + createMetadataFromTemplate(nodeTypeMetadata, metadata, nodeTemplateType); + } else { + createDefaultMetadata(nodeTypeMetadata, nodeTemplateType); + } + return nodeTypeMetadata; + } + + private void createMetadataFromTemplate(NodeTypeMetadata nodeTypeMetadata, Map metadata, String nodeTemplateType) { + nodeTypeMetadata.setToscaName(nodeTemplateType); + nodeTypeMetadata.setContactId(getModifier().getUserId()); + nodeTypeMetadata.setDescription((String) metadata.get("description")); + List tags = new ArrayList<>(); + tags.add((String) metadata.get("name")); + nodeTypeMetadata.setTags(tags); + SubCategoryDefinition subCategory = new SubCategoryDefinition(); + subCategory.setName((String) metadata.get("subcategory")); + CategoryDefinition category = new CategoryDefinition(); + category.setName((String) metadata.get("category")); + category.setNormalizedName(((String) metadata.get("category")).toLowerCase()); + category.setIcons(List.of(DEFAULT_ICON)); + category.setNormalizedName(((String) metadata.get("category")).toLowerCase()); + category.addSubCategory(subCategory); + List categories = new ArrayList<>(); + categories.add(category); + nodeTypeMetadata.setCategories(categories); + nodeTypeMetadata.setName((String) metadata.get("name")); + nodeTypeMetadata.setIcon("defaulticon"); + nodeTypeMetadata.setResourceVendorModelNumber((String) metadata.get("resourceVendorModelNumber")); + nodeTypeMetadata.setResourceType((String) metadata.get("type")); + nodeTypeMetadata.setVendorName((String) metadata.get("resourceVendor")); + nodeTypeMetadata.setVendorRelease((String) metadata.get("resourceVendorRelease")); + nodeTypeMetadata.setModel((String) metadata.get("model")); + nodeTypeMetadata.setNormative(false); + } + + private void createDefaultMetadata(NodeTypeMetadata nodeTypeMetadata, String nodeTemplateType) { + nodeTypeMetadata.setToscaName(nodeTemplateType); + nodeTypeMetadata.setContactId(getModifier().getUserId()); + nodeTypeMetadata.setDescription("A vfc of type " + nodeTemplateType); + Either, ResultStatusEnum> mainMetadataEither = ImportUtils.findFirstToscaMapElement(getMappedToscaMainTemplate(), + ToscaTagNamesEnum.METADATA); + Map mainMetadata = mainMetadataEither.left().value(); + nodeTypeMetadata.setModel((String) mainMetadata.get("model")); + SubCategoryDefinition subCategory = new SubCategoryDefinition(); + subCategory.setName("Network Elements"); + CategoryDefinition category = new CategoryDefinition(); + category.setName("Generic"); + category.setNormalizedName("generic"); + category.setIcons(List.of(DEFAULT_ICON)); + category.setNormalizedName("generic"); + category.addSubCategory(subCategory); + List categories = new ArrayList<>(); + categories.add(category); + nodeTypeMetadata.setCategories(categories); + String[] nodeTemplateName = nodeTemplateType.split("\\."); + String name = nodeTemplateName[nodeTemplateName.length - 1]; + nodeTypeMetadata.setName(name); + List tags = new ArrayList<>(); + tags.add(name); + nodeTypeMetadata.setTags(tags); + nodeTypeMetadata.setIcon("defaulticon"); + nodeTypeMetadata.setVendorName((String) mainMetadata.get("name")); + nodeTypeMetadata.setVendorRelease("1"); + nodeTypeMetadata.setNormative(false); + } + } diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java index d02a84f491..a20c30624e 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java @@ -169,11 +169,15 @@ public class ResourceImportManager { log.error(EcompLoggerErrorCode.BUSINESS_PROCESS_ERROR, ResourceImportManager.class.getName(), "Could not parse node types YAML", e); throw new ByActionStatusComponentException(ActionStatus.INVALID_NODE_TYPES_YAML); } - if (!nodeTypesYamlMap.containsKey(ToscaTagNamesEnum.NODE_TYPES.getElementName())) { return; } final Map nodeTypesMap = (Map) nodeTypesYamlMap.get(ToscaTagNamesEnum.NODE_TYPES.getElementName()); + importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList,user, createNewVersion,needLock); + } + + public void importAllNormativeResource(final Map nodeTypesMap, final NodeTypesMetadataList nodeTypesMetadataList, + final User user, final boolean createNewVersion, final boolean needLock) { try { nodeTypesMetadataList.getNodeMetadataList().forEach(nodeTypeMetadata -> { final String nodeTypeToscaName = nodeTypeMetadata.getToscaName(); @@ -358,7 +362,6 @@ public class ResourceImportManager { final Either existingResource = getExistingResource(resource); final Map toscaJsonAll = (Map) ymlObj; Map toscaJson = toscaJsonAll; - // Checks if exist and builds the node_types map if (toscaJsonAll.containsKey(ToscaTagNamesEnum.NODE_TYPES.getElementName()) && resource.getResourceType() != ResourceTypeEnum.CVFC) { toscaJson = new HashMap<>(); toscaJson.put(ToscaTagNamesEnum.NODE_TYPES.getElementName(), toscaJsonAll.get(ToscaTagNamesEnum.NODE_TYPES.getElementName())); @@ -372,7 +375,6 @@ public class ResourceImportManager { resource.setDataTypes(extractDataTypeFromJson(resourceBusinessLogic, toscaAttributes, resource.getModel())); } } - // Derived From final Resource parentResource = setDerivedFrom(toscaJson, resource); if (StringUtils.isEmpty(resource.getToscaResourceName())) { setToscaResourceName(toscaJson, resource); diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java index e4129a24eb..7b328f755d 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java @@ -37,8 +37,6 @@ import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.regex.Pattern; -import java.util.stream.Collectors; -import java.util.stream.Stream; import lombok.Getter; import lombok.Setter; import org.apache.commons.collections.CollectionUtils; @@ -84,7 +82,6 @@ import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.CapabilityRequirementRelationship; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.ComponentInstance; -import org.openecomp.sdc.be.model.ComponentInstanceAttribute; import org.openecomp.sdc.be.model.ComponentInstanceInput; import org.openecomp.sdc.be.model.ComponentInstanceProperty; import org.openecomp.sdc.be.model.ComponentParametersView; @@ -94,7 +91,10 @@ import org.openecomp.sdc.be.model.GroupDefinition; import org.openecomp.sdc.be.model.InputDefinition; import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.NodeTypeDefinition; import org.openecomp.sdc.be.model.NodeTypeInfo; +import org.openecomp.sdc.be.model.NodeTypeMetadata; +import org.openecomp.sdc.be.model.NodeTypesMetadataList; import org.openecomp.sdc.be.model.Operation; import org.openecomp.sdc.be.model.OutputDefinition; import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; @@ -168,6 +168,7 @@ public class ServiceImportBusinessLogic { private final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic; private final GroupBusinessLogic groupBusinessLogic; private final PolicyBusinessLogic policyBusinessLogic; + private final ResourceImportManager resourceImportManager; private final JanusGraphDao janusGraphDao; private final ArtifactsBusinessLogic artifactsBusinessLogic; private final IGraphLockOperation graphLockOperation; @@ -189,7 +190,9 @@ public class ServiceImportBusinessLogic { final ComponentNodeFilterBusinessLogic componentNodeFilterBusinessLogic, final PolicyBusinessLogic policyBusinessLogic, final JanusGraphDao janusGraphDao, final IGraphLockOperation graphLockOperation, final ToscaFunctionService toscaFunctionService, - final PropertyOperation propertyOperation, final DataTypeBusinessLogic dataTypeBusinessLogic) { + final PropertyOperation propertyOperation, final DataTypeBusinessLogic dataTypeBusinessLogic, + ResourceImportManager resourceImportManager) { + this.resourceImportManager = resourceImportManager; this.componentInstanceBusinessLogic = componentInstanceBusinessLogic; this.uiComponentDataConverter = uiComponentDataConverter; this.componentsUtils = componentsUtils; @@ -211,7 +214,7 @@ public class ServiceImportBusinessLogic { this.propertyOperation = propertyOperation; this.dataTypeBusinessLogic = dataTypeBusinessLogic; } - + @Autowired public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) { this.applicationDataTypeCache = applicationDataTypeCache; @@ -249,12 +252,15 @@ public class ServiceImportBusinessLogic { log.trace("************* created successfully from YAML, resource TOSCA "); try { ServiceCsarInfo csarInfo = csarBusinessLogic.getCsarInfo(service, null, user, csarUIPayload, csarUUID); - + final Map dataTypesToCreate = getDatatypesToCreate(service.getModel(), csarInfo); if (MapUtils.isNotEmpty(dataTypesToCreate)) { dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), service.getModel(), true); } - + final List nodeTypesToCreate = getNodeTypesToCreate(service.getModel(), csarInfo); + if (CollectionUtils.isNotEmpty(nodeTypesToCreate)) { + createNodeTypes(nodeTypesToCreate, csarInfo); + } Map nodeTypesInfo = csarInfo.extractTypesInfo(); Either>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = serviceImportParseLogic .findNodeTypesArtifactsToHandle(nodeTypesInfo, csarInfo, service); @@ -272,7 +278,7 @@ public class ServiceImportBusinessLogic { throw new ComponentException(ActionStatus.GENERAL_ERROR); } } - + private Map getDatatypesToCreate(final String model, final CsarInfo csarInfo) { final Map dataTypesToCreate = new HashMap<>(); @@ -286,6 +292,33 @@ public class ServiceImportBusinessLogic { return dataTypesToCreate; } + private void createNodeTypes(List nodeTypesToCreate, ServiceCsarInfo csarInfo) { + NodeTypesMetadataList nodeTypesMetadataList = new NodeTypesMetadataList(); + List nodeTypeMetadataList = new ArrayList<>(); + + final Map allTypesToCreate = new HashMap<>(); + nodeTypesToCreate.stream().forEach(nodeType -> { + allTypesToCreate.put(nodeType.getMappedNodeType().getKey(), nodeType.getMappedNodeType().getValue()); + nodeTypeMetadataList.add(nodeType.getNodeTypeMetadata()); + }); + + nodeTypesMetadataList.setNodeMetadataList(nodeTypeMetadataList); + resourceImportManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, csarInfo.getModifier(), true, false); + } + + private List getNodeTypesToCreate(final String model, final ServiceCsarInfo csarInfo) { + List namesOfNodeTypesToCreate = new ArrayList<>(); + + for (final NodeTypeDefinition nodeTypeDefinition : csarInfo.getNodeTypesUsed()) { + Either result = toscaOperationFacade + .getLatestByToscaResourceName(nodeTypeDefinition.getMappedNodeType().getKey(), model); + if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + namesOfNodeTypesToCreate.add(nodeTypeDefinition); + } + } + return namesOfNodeTypesToCreate; + } + protected Service createServiceFromYaml(Service service, String topologyTemplateYaml, String yamlName, Map nodeTypesInfo, CsarInfo csarInfo, Map>> nodeTypesArtifactsToCreate, diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java index 32d174f194..04a87e1db4 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java @@ -29,10 +29,13 @@ import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertThrows; import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.fail; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyMap; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.contains; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -40,13 +43,17 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import fj.data.Either; +import java.io.File; import java.io.IOException; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Optional; +import java.util.Set; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.collections4.MapUtils; import org.apache.commons.lang3.tuple.ImmutablePair; @@ -55,6 +62,7 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.mockito.stubbing.Answer; import org.openecomp.sdc.be.auditing.impl.AuditingManager; +import org.openecomp.sdc.be.components.csar.ServiceCsarInfo; import org.openecomp.sdc.be.components.impl.ImportUtils; import org.openecomp.sdc.be.components.impl.ImportUtilsTest; import org.openecomp.sdc.be.components.impl.InterfaceDefinitionHandler; @@ -80,6 +88,7 @@ import org.openecomp.sdc.be.impl.ComponentsUtils; import org.openecomp.sdc.be.model.CapabilityDefinition; import org.openecomp.sdc.be.model.Component; import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.NodeTypeDefinition; import org.openecomp.sdc.be.model.NodeTypeMetadata; import org.openecomp.sdc.be.model.NodeTypesMetadataList; import org.openecomp.sdc.be.model.PropertyConstraint; @@ -98,6 +107,8 @@ import org.openecomp.sdc.be.utils.TypeUtils; import org.openecomp.sdc.common.api.ConfigurationSource; 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 org.openecomp.sdc.exception.PolicyException; import org.openecomp.sdc.exception.ResponseFormat; @@ -463,6 +474,30 @@ class ResourceImportManagerTest { assertEquals(ActionStatus.COMPONENT_WITH_VENDOR_RELEASE_ALREADY_EXISTS, actualException.getActionStatus()); } + @Test + void getAllResourcesYamlAndNodeTypesMetadataListTest() { + NodeTypesMetadataList nodeTypesMetadataList = new NodeTypesMetadataList(); + List nodeTypeMetadataList = new ArrayList<>(); + Map allTypesToCreate = new HashMap<>(); + ServiceCsarInfo csarInfo= getCsarInfo(); + List nodeTypesToCreate = csarInfo.getNodeTypesUsed(); + nodeTypesToCreate.stream().forEach(nodeType -> { + allTypesToCreate.put(nodeType.getMappedNodeType().getKey(), nodeType.getMappedNodeType().getValue()); + nodeTypeMetadataList.add(nodeType.getNodeTypeMetadata()); + }); + nodeTypesMetadataList.setNodeMetadataList(nodeTypeMetadataList); + + when(toscaOperationFacade.getLatestByName(any(), any())).thenReturn(Either.left(null)).thenReturn(Either.left(null)); + when(toscaOperationFacade.getLatestByToscaResourceName("org.openecomp.resource.VFC-root", "ETSI SOL001 v2.5.1")) + .thenReturn(Either.left(null)); + when(resourceBusinessLogic + .createOrUpdateResourceByImport(any(Resource.class), any(User.class), eq(true), eq(true), eq(false), eq(null), eq(null), eq(false))) + .thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.OK)).thenReturn(new ImmutablePair<>(new Resource(), ActionStatus.OK)); + + importManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, user, false, false); + verify(janusGraphDao).commit(); + } + private void setResourceBusinessLogicMock() { when(resourceBusinessLogic.getUserAdmin()).thenReturn(userAdmin); when(resourceBusinessLogic.createOrUpdateResourceByImport(any(Resource.class), any(User.class), anyBoolean(), anyBoolean(), anyBoolean(), @@ -718,4 +753,29 @@ class ResourceImportManagerTest { assertEquals(ImportUtils.Constants.VENDOR_RELEASE, resource.getVendorRelease()); } + protected ServiceCsarInfo getCsarInfo() { + String csarUuid = "0010"; + User user = new User("jh0003"); + + try { + File csarFile = new File( + ResourceImportManagerTest.class.getClassLoader().getResource("csars/service-Etsiwithchild-csar.csar").toURI()); + Map csar = ZipUtils.readZip(csarFile, false); + + String vfReousrceName = "resouceName"; + String mainTemplateName = "Definitions/service-Etsiwithchild-template.yml"; + + Optional keyOp = csar.keySet().stream().filter(k -> k.endsWith("service-Etsiwithchild-template.yml")).findAny(); + byte[] mainTemplateService = keyOp.map(csar::get).orElse(null); + assertNotNull(mainTemplateService); + final String mainTemplateContent = new String(mainTemplateService); + + return new ServiceCsarInfo(user, csarUuid, csar, vfReousrceName, mainTemplateName, mainTemplateContent, false); + } catch (URISyntaxException | ZipException e) { + fail(e); + } + return null; + } + + } diff --git a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java index d40bac1585..3671ba7828 100644 --- a/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java +++ b/catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java @@ -204,6 +204,9 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest when(applicationDataTypeCache.get(any(), contains("tosca.datatypes.test_"))).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND)); when(applicationDataTypeCache.get(any(), matches("^((?!tosca.datatypes.test_).)*$"))).thenReturn(Either.left(new DataTypeDefinition())); + when(toscaOperationFacade.getLatestByToscaResourceName(contains("org.openecomp.resource"), isNull())).thenReturn(Either.left(null)); + when(toscaOperationFacade.getLatestByToscaResourceName(contains("tosca.nodes."), isNull())).thenReturn(Either.left(null)); + Service result = sIBL.createService(oldService, AuditingActionEnum.CREATE_RESOURCE, user, payload, payloadName); assertNotNull(result); assertNotNull(result.getComponentInstances()); diff --git a/catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csar b/catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csar new file mode 100644 index 0000000000..bd6e7a2858 Binary files /dev/null and b/catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csar differ diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java new file mode 100644 index 0000000000..99639f8d8e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java @@ -0,0 +1,14 @@ +package org.openecomp.sdc.be.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +import java.util.Map; + +@Getter +@AllArgsConstructor +public class NodeTypeDefinition { + + private Map.Entry mappedNodeType; + private NodeTypeMetadata nodeTypeMetadata; +} -- cgit 1.2.3-korg