summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJvD_Ericsson <jeff.van.dam@est.tech>2022-07-22 10:25:52 +0100
committerMichael Morris <michael.morris@est.tech>2022-08-12 09:00:45 +0000
commitc2ead8ac02672ab9af997272e211b0f0992288a1 (patch)
treedc384593cce5c9ca55ccd50e1f504535203865be
parent7952ce203e89fad3103b0ec17a41d240004c92e9 (diff)
Service import - Import unknown node types
Issue-ID: SDC-4118 Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech> Change-Id: Id620eef55ffb6849006e8a7bc063709150628e76
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/CsarInfo.java16
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java198
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java8
-rw-r--r--catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java49
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java60
-rw-r--r--catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java3
-rw-r--r--catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csarbin0 -> 50857 bytes
-rw-r--r--catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java14
8 files changed, 322 insertions, 26 deletions
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<String, Object> getTypesFromTemplate(final Map<String, Object> mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum type, Collection<String> names) {
+ Map<String, Object> allTypes = getTypesFromTemplate(mappedToscaTemplate, type);
+
+ final Map<String, Object> typesToReturn = new HashMap<>();
+ final Stream<Map.Entry<String, Object>> requestedTypes = allTypes.entrySet().stream().filter(entry -> names.contains(entry.getKey()));
+
+ requestedTypes.forEach(requestedType -> {
+ typesToReturn.put(requestedType.getKey(), requestedType.getValue());
+ });
+
+ return typesToReturn;
+ }
+
protected Set<String> findNodeTypesUsedInNodeTemplates(final Map<String, Map<String, Object>> nodeTemplates) {
final Set<String> nodeTypes = new HashSet<>();
for (final Map<String, Object> 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<String, Map<String, Object>> mainTemplateImports;
private static final Logger log = Logger.getLogger(ServiceCsarInfo.class);
+ private final Map<String, Map<String, Object>> mainTemplateImports;
+ private List<NodeTypeDefinition> nodeTypeDefinitions;
public ServiceCsarInfo(final User modifier, final String csarUUID, final Map<String, byte[]> 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<String, Map<String, Object>> getTemplateImports(final Map<String, byte[]> csar, Map<String, Object> mappedToscaMainTemplate,
- final Path fileParentDir, final Collection<Path> filesHandled) {
+ final Path fileParentDir, final Collection<Path> filesHandled) {
final Map<String, Map<String, Object>> templateImports = new HashMap<>();
- final List<Path> importFilePaths = getTempateImportFilePaths(mappedToscaMainTemplate, fileParentDir);
+ final List<Path> 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<String, Object> 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<Path> getTempateImportFilePaths(final Map<String, Object> mappedToscaTemplate, final Path fileParentDir) {
+ private List<Path> getTemplateImportFilePaths(final Map<String, Object> mappedToscaTemplate, final Path fileParentDir) {
final Either<Object, ResultStatusEnum> 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<Path> 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<Path> getTemplateImportFilePathsMultiLineGrammar(final List<Map<String, Object>> importsList, final Path fileParentDir) {
final List<Path> importFiles = new ArrayList<>();
- for (Map<String, Object> importFileMultiLineGrammar : (List<Map<String, Object>>) importsList) {
+ for (Map<String, Object> 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<String, Object> getDataTypes() {
final Map<String, Object> 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<NodeTypeDefinition> getNodeTypesUsed() {
+ if (nodeTypeDefinitions == null) {
+ nodeTypeDefinitions = new ArrayList<>();
+ final Set<String> nodeTypesUsed = getNodeTypesUsedInToscaTemplate(getMappedToscaMainTemplate());
+ nodeTypeDefinitions.addAll(getNodeTypeDefinitions(nodeTypesUsed));
+ }
+ nodeTypeDefinitions = sortNodeTypesByDependencyOrder(nodeTypeDefinitions);
+ return nodeTypeDefinitions;
+ }
+
+ private List<NodeTypeDefinition> sortNodeTypesByDependencyOrder(final List<NodeTypeDefinition> nodeTypes) {
+ final List<NodeTypeDefinition> sortedNodeTypeDefinitions = new ArrayList<>();
+ final Map<String, NodeTypeDefinition> 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<String> getDependencyTypes(final NodeTypeDefinition nodeType, final List<NodeTypeDefinition> nodeTypes) {
+ final Set<String> dependencies = new HashSet<>();
+ Either<Object, ResultStatusEnum> derivedFromTypeEither = findToscaElement((Map<String, Object>) 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<NodeTypeDefinition> getNodeTypeDefinitions(final Set<String> nodeTypesToGet) {
+ final Set<NodeTypeDefinition> nodeTypesToReturn = new HashSet<>();
+ final Set<NodeTypeDefinition> foundNodeTypes = getTypes(nodeTypesToGet);
+ nodeTypesToReturn.addAll(foundNodeTypes);
+ final Set<String> recursiveNodeTypesToGet = new HashSet<>();
+ foundNodeTypes.stream().forEach(nodeTypeDef -> {
+ Either<Object, ResultStatusEnum> derivedFromTypeEither =
+ findToscaElement((Map<String, Object>) 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<NodeTypeDefinition> getTypes(final Set<String> nodeTypes) {
+ Set<NodeTypeDefinition> nodeTypeDefinitionsLocal = new HashSet<>();
+ mainTemplateImports.entrySet().forEach(entry -> {
+ final Map<String, Object> 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<String> getNodeTypesUsedInToscaTemplate(Map<String, Object> mappedToscaTemplate) {
+ final Either<Object, ResultStatusEnum> nodeTemplatesEither = findToscaElement(mappedToscaTemplate,
+ TypeUtils.ToscaTagNamesEnum.NODE_TEMPLATES, ToscaElementTypeEnum.MAP);
+ final Set<String> nodeTypesUsedInNodeTemplates = new HashSet<>();
+ if (nodeTemplatesEither.isLeft()) {
+ final Map<String, Map<String, Object>> nodeTemplates =
+ (Map<String, Map<String, Object>>) nodeTemplatesEither.left().value();
+ nodeTypesUsedInNodeTemplates.addAll(findNodeTypesUsedInNodeTemplates(nodeTemplates));
+ }
+ return nodeTypesUsedInNodeTemplates;
+ }
+
+ private NodeTypeMetadata getMetaDataFromTemplate(Map<String, Object> mappedResourceTemplate, String nodeTemplateType) {
+ NodeTypeMetadata nodeTypeMetadata = new NodeTypeMetadata();
+ Either<Map<String, Object>, ImportUtils.ResultStatusEnum> metadataEither = ImportUtils.findFirstToscaMapElement(mappedResourceTemplate, TypeUtils.ToscaTagNamesEnum.METADATA);
+ if (metadataEither.isLeft() && metadataEither.left().value().get("type").equals(ResourceTypeEnum.VFC.getValue())) {
+ Map<String, Object> metadata = metadataEither.left().value();
+ createMetadataFromTemplate(nodeTypeMetadata, metadata, nodeTemplateType);
+ } else {
+ createDefaultMetadata(nodeTypeMetadata, nodeTemplateType);
+ }
+ return nodeTypeMetadata;
+ }
+
+ private void createMetadataFromTemplate(NodeTypeMetadata nodeTypeMetadata, Map<String, Object> metadata, String nodeTemplateType) {
+ nodeTypeMetadata.setToscaName(nodeTemplateType);
+ nodeTypeMetadata.setContactId(getModifier().getUserId());
+ nodeTypeMetadata.setDescription((String) metadata.get("description"));
+ List<String> 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<CategoryDefinition> 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<Map<String, Object>, ResultStatusEnum> mainMetadataEither = ImportUtils.findFirstToscaMapElement(getMappedToscaMainTemplate(),
+ ToscaTagNamesEnum.METADATA);
+ Map<String, Object> 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<CategoryDefinition> categories = new ArrayList<>();
+ categories.add(category);
+ nodeTypeMetadata.setCategories(categories);
+ String[] nodeTemplateName = nodeTemplateType.split("\\.");
+ String name = nodeTemplateName[nodeTemplateName.length - 1];
+ nodeTypeMetadata.setName(name);
+ List<String> 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<String, Object> nodeTypesMap = (Map<String, Object>) nodeTypesYamlMap.get(ToscaTagNamesEnum.NODE_TYPES.getElementName());
+ importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList,user, createNewVersion,needLock);
+ }
+
+ public void importAllNormativeResource(final Map<String, Object> 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<Resource, StorageOperationStatus> existingResource = getExistingResource(resource);
final Map<String, Object> toscaJsonAll = (Map<String, Object>) ymlObj;
Map<String, Object> 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<String, Object> dataTypesToCreate = getDatatypesToCreate(service.getModel(), csarInfo);
if (MapUtils.isNotEmpty(dataTypesToCreate)) {
dataTypeBusinessLogic.createDataTypeFromYaml(new Yaml().dump(dataTypesToCreate), service.getModel(), true);
}
-
+ final List<NodeTypeDefinition> nodeTypesToCreate = getNodeTypesToCreate(service.getModel(), csarInfo);
+ if (CollectionUtils.isNotEmpty(nodeTypesToCreate)) {
+ createNodeTypes(nodeTypesToCreate, csarInfo);
+ }
Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = serviceImportParseLogic
.findNodeTypesArtifactsToHandle(nodeTypesInfo, csarInfo, service);
@@ -272,7 +278,7 @@ public class ServiceImportBusinessLogic {
throw new ComponentException(ActionStatus.GENERAL_ERROR);
}
}
-
+
private Map<String, Object> getDatatypesToCreate(final String model, final CsarInfo csarInfo) {
final Map<String, Object> dataTypesToCreate = new HashMap<>();
@@ -286,6 +292,33 @@ public class ServiceImportBusinessLogic {
return dataTypesToCreate;
}
+ private void createNodeTypes(List<NodeTypeDefinition> nodeTypesToCreate, ServiceCsarInfo csarInfo) {
+ NodeTypesMetadataList nodeTypesMetadataList = new NodeTypesMetadataList();
+ List<NodeTypeMetadata> nodeTypeMetadataList = new ArrayList<>();
+
+ final Map<String, Object> 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<NodeTypeDefinition> getNodeTypesToCreate(final String model, final ServiceCsarInfo csarInfo) {
+ List<NodeTypeDefinition> namesOfNodeTypesToCreate = new ArrayList<>();
+
+ for (final NodeTypeDefinition nodeTypeDefinition : csarInfo.getNodeTypesUsed()) {
+ Either<Component, StorageOperationStatus> 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<String, NodeTypeInfo> nodeTypesInfo,
CsarInfo csarInfo,
Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> 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<NodeTypeMetadata> nodeTypeMetadataList = new ArrayList<>();
+ Map<String, Object> allTypesToCreate = new HashMap<>();
+ ServiceCsarInfo csarInfo= getCsarInfo();
+ List<NodeTypeDefinition> 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<String, byte[]> csar = ZipUtils.readZip(csarFile, false);
+
+ String vfReousrceName = "resouceName";
+ String mainTemplateName = "Definitions/service-Etsiwithchild-template.yml";
+
+ Optional<String> 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
--- /dev/null
+++ b/catalog-be/src/test/resources/csars/service-Etsiwithchild-csar.csar
Binary files 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<String, Object> mappedNodeType;
+ private NodeTypeMetadata nodeTypeMetadata;
+}