Support import of updated node types 93/130293/18
authorJvD_Ericsson <jeff.van.dam@est.tech>
Mon, 15 Aug 2022 12:40:19 +0000 (13:40 +0100)
committerMichael Morris <michael.morris@est.tech>
Tue, 6 Sep 2022 16:45:46 +0000 (16:45 +0000)
Support addition of new properties

Issue-ID: SDC-4131
Signed-off-by: JvD_Ericsson <jeff.van.dam@est.tech>
Change-Id: I9f12d0f4f9727c33f8444980b780758533e714cf

catalog-be/src/main/java/org/openecomp/sdc/be/components/csar/ServiceCsarInfo.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBussinessLogicBaseTestSetup.java
catalog-be/src/test/resources/node-types/resource-Extcp-template.yml [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/DefaultUploadResourceInfo.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/NodeTypeDefinition.java
catalog-model/src/main/java/org/openecomp/sdc/be/model/NullNodeTypeMetadata.java [new file with mode: 0644]
catalog-model/src/main/java/org/openecomp/sdc/be/model/mapper/NodeTypeMetadataMapper.java

index 5c94832..08f777d 100644 (file)
@@ -44,6 +44,7 @@ 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.NullNodeTypeMetadata;
 import org.openecomp.sdc.be.model.User;
 import org.openecomp.sdc.be.model.category.CategoryDefinition;
 import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
@@ -173,7 +174,7 @@ public class ServiceCsarInfo extends CsarInfo {
                 highestDependencyIndex = indexOfDependency > highestDependencyIndex ? indexOfDependency : highestDependencyIndex;
             }
             sortedNodeTypeDefinitions.add(highestDependencyIndex + 1, nodeType);
-            nodeTypeDefinitionsMap.put(nodeType.getNodeTypeMetadata().getToscaName(), nodeType);
+            nodeTypeDefinitionsMap.put(nodeType.getMappedNodeType().getKey(), nodeType);
         });
         return sortedNodeTypeDefinitions;
     }
@@ -185,7 +186,7 @@ public class ServiceCsarInfo extends CsarInfo {
         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()))
+            nodeTypes.stream().filter(derivedFromCandidate -> derivedFrom.contentEquals(derivedFromCandidate.getMappedNodeType().getKey()))
                 .forEach(derivedFromNodeType -> dependencies.addAll(getDependencyTypes(derivedFromNodeType, nodeTypes)));
         }
         return dependencies;
@@ -247,7 +248,7 @@ public class ServiceCsarInfo extends CsarInfo {
             Map<String, Object> metadata = metadataEither.left().value();
             createMetadataFromTemplate(nodeTypeMetadata, metadata, nodeTemplateType);
         } else {
-            createDefaultMetadata(nodeTypeMetadata, nodeTemplateType);
+            nodeTypeMetadata = createDefaultMetadata(nodeTemplateType);
         }
         return nodeTypeMetadata;
     }
@@ -275,40 +276,14 @@ public class ServiceCsarInfo extends CsarInfo {
         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.setVendorRelease(String.valueOf(metadata.get("resourceVendorRelease")));
         nodeTypeMetadata.setModel((String) metadata.get("model"));
         nodeTypeMetadata.setNormative(false);
     }
 
-    private void createDefaultMetadata(NodeTypeMetadata nodeTypeMetadata, String nodeTemplateType) {
+    private NullNodeTypeMetadata createDefaultMetadata(String nodeTemplateType) {
+        NullNodeTypeMetadata nodeTypeMetadata = new NullNodeTypeMetadata();
         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);
+        return nodeTypeMetadata;
     }
-
 }
index a20c306..79b3c96 100644 (file)
@@ -79,9 +79,11 @@ import org.openecomp.sdc.be.model.AttributeDefinition;
 import org.openecomp.sdc.be.model.CapabilityDefinition;
 import org.openecomp.sdc.be.model.ComponentInstanceProperty;
 import org.openecomp.sdc.be.model.DataTypeDefinition;
+import org.openecomp.sdc.be.model.DefaultUploadResourceInfo;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.LifecycleStateEnum;
 import org.openecomp.sdc.be.model.NodeTypesMetadataList;
+import org.openecomp.sdc.be.model.NullNodeTypeMetadata;
 import org.openecomp.sdc.be.model.PropertyDefinition;
 import org.openecomp.sdc.be.model.RequirementDefinition;
 import org.openecomp.sdc.be.model.Resource;
@@ -173,11 +175,11 @@ public class ResourceImportManager {
             return;
         }
         final Map<String, Object> nodeTypesMap = (Map<String, Object>) nodeTypesYamlMap.get(ToscaTagNamesEnum.NODE_TYPES.getElementName());
-        importAllNormativeResource(nodeTypesMap, nodeTypesMetadataList,user, createNewVersion,needLock);
+        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) {
+                                           final User user, String model, final boolean createNewVersion, final boolean needLock) {
         try {
             nodeTypesMetadataList.getNodeMetadataList().forEach(nodeTypeMetadata -> {
                 final String nodeTypeToscaName = nodeTypeMetadata.getToscaName();
@@ -191,7 +193,12 @@ public class ResourceImportManager {
                             Map.of(nodeTypeToscaName, nodeTypeMap)
                         );
                     final String nodeTypeYaml = new Yaml().dump(nodeTypeDefinitionMap);
-                    importNormativeResource(nodeTypeYaml, NodeTypeMetadataMapper.mapTo(nodeTypeMetadata), user, createNewVersion, needLock, true);
+                    UploadResourceInfo uploadResourceInfo = NodeTypeMetadataMapper.mapTo(nodeTypeMetadata);
+                    if (uploadResourceInfo instanceof DefaultUploadResourceInfo) {
+                        uploadResourceInfo.setModel(model);
+                        uploadResourceInfo.setContactId(user.getUserId());
+                    }
+                    importNormativeResource(nodeTypeYaml, uploadResourceInfo, user, createNewVersion, needLock, true);
                 }
             });
             janusGraphDao.commit();
@@ -225,7 +232,7 @@ public class ResourceImportManager {
         try {
             boolean shouldBeCertified = nodeTypeArtifactsToHandle == null || nodeTypeArtifactsToHandle.isEmpty();
             setConstantMetaData(resource, shouldBeCertified);
-            setMetaDataFromJson(resourceMetaData, resource);
+            setResourceMetaData(resource, resourceYml, resourceMetaData);
             populateResourceFromYaml(resourceYml, resource);
             validationFunction.apply(resource);
             resource.getComponentMetadataDefinition().getMetadataDataDefinition().setNormative(resourceMetaData.isNormative());
@@ -429,12 +436,17 @@ public class ResourceImportManager {
     }
 
     private void setToscaResourceName(Map<String, Object> toscaJson, Resource resource) {
+        resource.setToscaResourceName(getToscaResourceName(toscaJson));
+    }
+
+    private String getToscaResourceName(Map<String, Object> toscaJson) {
         Either<Map<String, Object>, ResultStatusEnum> toscaElement = ImportUtils
-            .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TYPES);
+                .findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TYPES);
         if (toscaElement.isLeft() && toscaElement.left().value().size() == 1) {
             String toscaResourceName = toscaElement.left().value().keySet().iterator().next();
-            resource.setToscaResourceName(toscaResourceName);
+            return toscaResourceName;
         }
+        return null;
     }
 
     private void setInterfaceLifecycle(Map<String, Object> toscaJson, Resource resource, Either<Resource, StorageOperationStatus> existingResource) {
@@ -576,13 +588,15 @@ public class ResourceImportManager {
                     addPropertyToList(resource.getName(), propertiesList, entry);
                 }
                 if (existingResource.isLeft()) {
-                    final List<PropertyDefinition> userCreatedResourceProperties =
-                        existingResource.left().value().getProperties().stream()
-                            .filter(PropertyDataDefinition::isUserCreated)
-                            .filter(propertyDefinition -> !propertyDefinitionMap.containsKey(propertyDefinition.getName()))
-                            .collect(Collectors.toList());
-                    if (CollectionUtils.isNotEmpty(userCreatedResourceProperties)) {
-                        propertiesList.addAll(userCreatedResourceProperties);
+                    if ( CollectionUtils.isNotEmpty(existingResource.left().value().getProperties())) {
+                        final List<PropertyDefinition> userCreatedResourceProperties =
+                            existingResource.left().value().getProperties().stream()
+                                .filter(PropertyDataDefinition::isUserCreated)
+                                .filter(propertyDefinition -> !propertyDefinitionMap.containsKey(propertyDefinition.getName()))
+                                .collect(Collectors.toList());
+                        if (CollectionUtils.isNotEmpty(userCreatedResourceProperties)) {
+                            propertiesList.addAll(userCreatedResourceProperties);
+                        }
                     }
                 }
 
@@ -876,6 +890,18 @@ public class ResourceImportManager {
         getAuditingManager().auditEvent(factory);
     }
 
+    private void setResourceMetaData(Resource resource, String resourceYml, UploadResourceInfo resourceMetaData) {
+        Map<String, Object> ymlObj = new Yaml().load(resourceYml);
+        String toscaName = getToscaResourceName(ymlObj);
+        final Either<Resource, StorageOperationStatus> latestByToscaName = toscaOperationFacade
+            .getLatestByToscaResourceName(toscaName, resourceMetaData.getModel());
+        if (latestByToscaName.isLeft() && resourceMetaData instanceof DefaultUploadResourceInfo) {
+            setMetaDataFromLatestResource(resource, latestByToscaName.left().value());
+        } else {
+            setMetaDataFromJson(resourceMetaData, resource);
+        }
+    }
+
     private void setMetaDataFromJson(final UploadResourceInfo resourceMetaData, final Resource resource) {
         this.populateResourceMetadata(resourceMetaData, resource);
         resource.setCreatorUserId(resourceMetaData.getContactId());
@@ -887,6 +913,34 @@ public class ResourceImportManager {
         calculateResourceIsAbstract(resource, categories);
     }
 
+    private void setMetaDataFromLatestResource(Resource resource, Resource latestResource) {
+        if (resource != null && latestResource != null) {
+            resource.setCreatorUserId(latestResource.getContactId());
+            resource.setDescription(latestResource.getDescription());
+            resource.setTags(latestResource.getTags());
+            resource.setCategories(latestResource.getCategories());
+            resource.setContactId(latestResource.getContactId());
+            resource.setName(latestResource.getName());
+            resource.setIcon(latestResource.getIcon());
+            resource.setResourceVendorModelNumber(latestResource.getResourceVendorModelNumber());
+            resource.setResourceType(latestResource.getResourceType());
+            if (latestResource.getVendorName() != null) {
+                resource.setVendorName(latestResource.getVendorName());
+            }
+            if (latestResource.getVendorRelease() != null) {
+                resource.setVendorRelease(latestResource.getVendorRelease());
+            }
+            if (latestResource.getModel() != null) {
+                resource.setModel(latestResource.getModel());
+            }
+            if (latestResource.getToscaVersion() != null) {
+                resource.setToscaVersion(latestResource.getToscaVersion());
+            }
+            final List<CategoryDefinition> categories = latestResource.getCategories();
+            calculateResourceIsAbstract(resource, categories);
+        }
+    }
+
     private Map<String, Object> decodePayload(final String payloadData) {
         final String decodedPayload = new String(Base64.decodeBase64(payloadData));
         return (Map<String, Object>) new Yaml().load(decodedPayload);
index b4079ac..0a7ce20 100644 (file)
@@ -19,6 +19,7 @@ import static java.util.stream.Collectors.joining;
 import static java.util.stream.Collectors.toList;
 import static java.util.stream.Collectors.toMap;
 import static org.apache.commons.collections.CollectionUtils.isNotEmpty;
+import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaMapElement;
 import static org.openecomp.sdc.be.components.impl.ImportUtils.findFirstToscaStringElement;
 import static org.openecomp.sdc.be.components.impl.ImportUtils.getPropertyJsonStringValue;
 import static org.openecomp.sdc.be.tosca.CsarUtils.VF_NODE_TYPE_ARTIFACTS_PATH_PATTERN;
@@ -131,6 +132,7 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
 import org.openecomp.sdc.be.tosca.CsarUtils;
+import org.openecomp.sdc.be.tosca.ToscaExportHandler;
 import org.openecomp.sdc.be.ui.model.OperationUi;
 import org.openecomp.sdc.be.utils.TypeUtils;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
@@ -256,7 +258,7 @@ public class ServiceImportBusinessLogic {
             }
             final List<NodeTypeDefinition> nodeTypesToCreate = getNodeTypesToCreate(service.getModel(), csarInfo);
             if (CollectionUtils.isNotEmpty(nodeTypesToCreate)) {
-                createNodeTypes(nodeTypesToCreate, csarInfo);
+                createNodeTypes(nodeTypesToCreate, service.getModel(), csarInfo.getModifier());
             }
             Map<String, NodeTypeInfo> nodeTypesInfo = csarInfo.extractTypesInfo();
             Either<Map<String, EnumMap<ArtifactOperationEnum, List<ArtifactDefinition>>>, ResponseFormat> findNodeTypesArtifactsToHandleRes = serviceImportParseLogic
@@ -299,18 +301,16 @@ public class ServiceImportBusinessLogic {
                 && result.left().value().getProperties().size() != dataType.get("properties").size();
     }
 
-    private void createNodeTypes(List<NodeTypeDefinition> nodeTypesToCreate, ServiceCsarInfo csarInfo) {
+    private void createNodeTypes(List<NodeTypeDefinition> nodeTypesToCreate, String model, User user) {
         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);
+        resourceImportManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, user, model,true, false);
     }
 
     private List<NodeTypeDefinition> getNodeTypesToCreate(final String model, final ServiceCsarInfo csarInfo) {
@@ -321,11 +321,62 @@ public class ServiceImportBusinessLogic {
                 .getLatestByToscaResourceName(nodeTypeDefinition.getMappedNodeType().getKey(), model);
             if (result.isRight() && result.right().value().equals(StorageOperationStatus.NOT_FOUND)) {
                 namesOfNodeTypesToCreate.add(nodeTypeDefinition);
+            } else if (result.isLeft()) {
+                Resource latestResource = (Resource) result.left().value();
+                Entry<String, Object> latestMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(),
+                        latestResource.getToscaArtifacts().get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE), csarInfo.getModifier().getUserId());
+                Map<String, Object> mappedToscaTemplate = (Map<String, Object>) nodeTypeDefinition.getMappedNodeType().getValue();
+                Map<String, Object> newMappedToscaTemplate =
+                        getNewChangesToToscaTemplate(mappedToscaTemplate, (Map<String, Object>) latestMappedToscaTemplate.getValue());
+                if (!newMappedToscaTemplate.equals(latestMappedToscaTemplate.getValue())) {
+                    latestMappedToscaTemplate.setValue(newMappedToscaTemplate);
+                    nodeTypeDefinition.setMappedNodeType(latestMappedToscaTemplate);
+                    namesOfNodeTypesToCreate.add(nodeTypeDefinition);
+                }
             }
         }
         return namesOfNodeTypesToCreate;
     }
 
+    private Entry<String, Object> getResourceToscaTemplate(String uniqueId, ArtifactDefinition assetToscaTemplate, String userId) {
+        String assetToToscaTemplate = assetToscaTemplate.getUniqueId();
+        ImmutablePair<String, byte[]> toscaTemplate = artifactsBusinessLogic.
+                handleDownloadRequestById(uniqueId, assetToToscaTemplate, userId, ComponentTypeEnum.RESOURCE, null, null);
+        Map<String, Object> mappedToscaTemplate = new Yaml().load(new String(toscaTemplate.right));
+        Either<Map<String, Object>, ImportUtils.ResultStatusEnum> eitherNodeTypes =
+                findFirstToscaMapElement(mappedToscaTemplate, TypeUtils.ToscaTagNamesEnum.NODE_TYPES);
+        if (eitherNodeTypes.isRight()) {
+            throw new ComponentException(ActionStatus.INVALID_TOSCA_TEMPLATE);
+        }
+        Entry<String, Object> entry = eitherNodeTypes.left().value().entrySet().iterator().next();
+        return entry;
+    }
+
+    private Map<String, Object> getNewChangesToToscaTemplate(Map<String, Object> mappedToscaTemplate, Map<String, Object> latestMappedToscaTemplate) {
+        Map<String, Object> newMappedToscaTemplate = new HashMap<>(latestMappedToscaTemplate);
+
+        Map<String, Object> properties = (Map<String, Object>) mappedToscaTemplate.get("properties");
+        Map<String, Object> latestProperties = (Map<String, Object>) latestMappedToscaTemplate.get("properties");
+        Map<String, Object> allProperties = combinedEntries(properties, latestProperties);
+        if ((MapUtils.isEmpty(latestProperties) && MapUtils.isNotEmpty(allProperties)) ||
+            (MapUtils.isNotEmpty(latestProperties) && !allProperties.equals(latestProperties))) {
+            newMappedToscaTemplate.put("properties", allProperties);
+        }
+        return newMappedToscaTemplate;
+    }
+
+    private Map<String, Object> combinedEntries(Map<String, Object> firstMap, Map<String, Object> secondMap) {
+        if (MapUtils.isEmpty(firstMap)) {
+            firstMap = new HashMap<>();
+        }
+        Map<String, Object> combinedEntries = new HashMap<>(firstMap);
+        if (MapUtils.isEmpty(secondMap)) {
+            return combinedEntries;
+        }
+        combinedEntries.putAll(secondMap);
+        return combinedEntries;
+    }
+
     protected Service createServiceFromYaml(Service service, String topologyTemplateYaml, String yamlName, Map<String, NodeTypeInfo> nodeTypesInfo,
                                             CsarInfo csarInfo,
                                             Map<String, EnumMap<ArtifactsBusinessLogic.ArtifactOperationEnum, List<ArtifactDefinition>>> nodeTypesArtifactsToCreate,
index 04a87e1..9c58372 100644 (file)
@@ -494,7 +494,7 @@ class ResourceImportManagerTest {
                 .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);
+        importManager.importAllNormativeResource(allTypesToCreate, nodeTypesMetadataList, user, "", false, false);
         verify(janusGraphDao).commit();
     }
 
index 3f8f9c3..a77ef5b 100644 (file)
@@ -115,6 +115,7 @@ import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus;
 import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum;
 import org.openecomp.sdc.be.servlets.AbstractValidationsServlet;
 import org.openecomp.sdc.be.tosca.CsarUtils;
+import org.openecomp.sdc.be.tosca.ToscaExportHandler;
 import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum;
 import org.openecomp.sdc.common.api.ArtifactTypeEnum;
 import org.openecomp.sdc.common.api.Constants;
@@ -173,6 +174,18 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest
         jsonObject.put(ToscaGetFunctionType.GET_INPUT.getFunctionName(), "zxjTestImportServiceAb_propertiesName");
         componentInstanceProperty.setValue(jsonObject.toJSONString());
 
+        Map<String, ArtifactDefinition> toscaArtifacts = new HashMap<>();
+        ArtifactDefinition artifactDef = new ArtifactDefinition();
+        String artifactUniqueId = "test_extcp_resource.assettoscatemplate";
+        artifactDef.setUniqueId(artifactUniqueId);
+        toscaArtifacts.put(ToscaExportHandler.ASSET_TOSCA_TEMPLATE, artifactDef);
+        Resource resource = new Resource();
+        String resourceUniqueId = "extcp_resource";
+        resource.setUniqueId(resourceUniqueId);
+        resource.setToscaArtifacts(toscaArtifacts);
+        ImmutablePair<String, byte[]> resourceTemplate = getNodeType();
+        String updatedNodeType = "org.openecomp.resource.cp.extCP";
+
         newService.setComponentInstancesProperties(
             Collections.singletonMap(COMPONENT_ID + "." + "zxjTestImportServiceAb", Collections.singletonList(componentInstanceProperty)));
         newService.setProperties(getProperties());
@@ -234,8 +247,13 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest
 
 
 
-        when(toscaOperationFacade.getLatestByToscaResourceName(contains("org.openecomp.resource"), isNull())).thenReturn(Either.left(null));
-        when(toscaOperationFacade.getLatestByToscaResourceName(contains("tosca.nodes."), isNull())).thenReturn(Either.left(null));
+        when(toscaOperationFacade.getLatestByToscaResourceName(contains("org.openecomp.resource"), isNull()))
+                .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+        when(toscaOperationFacade.getLatestByToscaResourceName(contains("tosca.nodes."), isNull()))
+                .thenReturn(Either.right(StorageOperationStatus.NOT_FOUND));
+        when(toscaOperationFacade.getLatestByToscaResourceName(contains(updatedNodeType), isNull())).thenReturn(Either.left(resource));
+        when(artifactsBusinessLogic.handleDownloadRequestById(resourceUniqueId, artifactUniqueId, user.getUserId(), ComponentTypeEnum.RESOURCE, null, null))
+                .thenReturn(resourceTemplate);
         when(toscaOperationFacade.updatePropertyOfComponent(eq(oldService), any(PropertyDefinition.class))).thenReturn(Either.left(null));
         when(toscaOperationFacade.updateComponentInstancePropsToComponent(anyMap(), anyString())).thenReturn(Either.left(null));
 
@@ -258,6 +276,13 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest
         assertNotNull(yamlMap.get("tosca.datatypes.test_a"));
         assertNotNull(yamlMap.get("tosca.datatypes.test_b"));
         assertNotNull(yamlMap.get("onap.datatypes.ToscaConceptIdentifier"));
+
+        ArgumentCaptor<Map<String, Object>> nodeTypes = ArgumentCaptor.forClass(Map.class);
+        verify(resourceImportManager).importAllNormativeResource(nodeTypes.capture(), any(), any(), any(),
+                anyBoolean(), anyBoolean());
+        Map<String, Object> nodeTypesMap = nodeTypes.getValue();
+        Map<String, Object> newUpdatedNodeType = (Map<String, Object>) nodeTypesMap.get(updatedNodeType);
+        assertEquals(8, ((Map<String, Object>) newUpdatedNodeType.get("properties")).size());
     }
 
     @Test
@@ -2431,6 +2456,19 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest
         return null;
     }
 
+    private ImmutablePair<String, byte[]> getNodeType() {
+        try {
+            File resource = new File(
+                    ServiceImportBusinessLogicTest.class.getClassLoader().getResource("node-types/resource-Extcp-template.yml").toURI());
+            byte[] extcpResource = Files.readAllBytes(resource.toPath());
+
+            return new ImmutablePair<>("org.openecomp.resource.cp.extCP", extcpResource);
+        } catch (URISyntaxException | IOException e) {
+            fail(e);
+        }
+        return null;
+    }
+
     protected CsarUtils.NonMetaArtifactInfo getNonMetaArtifactInfo() {
         String artifactName = "artifactName", path = "/src/test/resources/valid_vf.csar", artifactType = "AAI_SERVICE_MODEL";
         ArtifactGroupTypeEnum artifactGroupType = ArtifactGroupTypeEnum.TOSCA;
index fd39b65..ecec834 100644 (file)
@@ -131,7 +131,6 @@ public class ServiceImportBussinessLogicBaseTestSetup extends BaseBusinessLogicM
     private static final String RESOURCE_SUBCATEGORY = "Router";
 
     private final ArtifactDefinition artifactDefinition = mock(ArtifactDefinition.class);
-    private final ResourceImportManager resourceImportManager = mock(ResourceImportManager.class);
     private final ServletUtils servletUtils = mock(ServletUtils.class);
 
     protected final ServletContext servletContext = mock(ServletContext.class);
diff --git a/catalog-be/src/test/resources/node-types/resource-Extcp-template.yml b/catalog-be/src/test/resources/node-types/resource-Extcp-template.yml
new file mode 100644 (file)
index 0000000..4302a12
--- /dev/null
@@ -0,0 +1,95 @@
+tosca_definitions_version: tosca_simple_yaml_1_3
+metadata:
+  invariantUUID: 93047af6-cd60-401a-b60b-346d67314aeb
+  UUID: e6e6753a-11a7-41d3-b563-90e4a2e5606d
+  name: ExtCP
+  description: The AT&T Connection Point base type all other CP derive from
+  model:
+  category: Generic
+  type: CP
+  subcategory: Network Elements
+  resourceVendor: ONAP (Tosca)
+  resourceVendorRelease: 1.0.0.wd03
+  reourceVendorModelNumber: ''
+imports:
+- nodes:
+    file: nodes.yml
+- datatypes:
+    file: data.yml
+- capabilities:
+    file: capabilities.yml
+- relationships:
+    file: relationships.yml
+- groups:
+    file: groups.yml
+- policies:
+    file: policies.yml
+node_types:
+  org.openecomp.resource.cp.extCP:
+    derived_from: tosca.nodes.Root
+    description: The AT&T Connection Point base type all other CP derive from
+    properties:
+      ip_requirements:
+        type: list
+        description: identifies IP requirements to the CP
+        required: true
+        entry_schema:
+          type: org.openecomp.datatypes.network.IpRequirements
+      network_role:
+        type: string
+        description: identical to VL network_role
+        required: true
+      subnetpoolid:
+        type: string
+        required: false
+      mac_requirements:
+        default:
+          mac_count_required:
+            is_required: false
+        type: org.openecomp.datatypes.network.MacRequirements
+        description: identifies MAC address assignments to the CP
+        required: false
+      exCP_naming:
+        default:
+          ecomp_generated_naming: true
+        type: org.openecomp.datatypes.Naming
+        required: false
+      vlan_requirements:
+        type: list
+        description: identifies vlan address assignments to the CP
+        required: false
+        entry_schema:
+          type: org.openecomp.datatypes.network.VlanRequirements
+      network_role_tag:
+        type: string
+        description: Must correlate to the set of defined network-role tag identifiers
+          from the associated HEAT template
+        required: true
+    capabilities:
+      internal_connectionPoint:
+        type: tosca.capabilities.Node
+        occurrences:
+        - 0
+        - UNBOUNDED
+        valid_source_types:
+        - tosca.nodes.network.Port
+    requirements:
+    - virtualBinding:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.network.Bindable
+        relationship: tosca.relationships.network.BindsTo
+    - virtualLink:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.network.Linkable
+        relationship: tosca.relationships.network.LinksTo
+    - external_virtualLink:
+        occurrences:
+        - 0
+        - UNBOUNDED
+        capability: tosca.capabilities.network.Linkable
+        node: org.openecomp.resource.vl.VL
+        relationship: tosca.relationships.network.LinksTo
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DefaultUploadResourceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DefaultUploadResourceInfo.java
new file mode 100644 (file)
index 0000000..3b8a6cd
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+package org.openecomp.sdc.be.model;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.openecomp.sdc.be.model.category.CategoryDefinition;
+import org.openecomp.sdc.be.model.category.SubCategoryDefinition;
+
+public class DefaultUploadResourceInfo extends UploadResourceInfo{
+
+    public DefaultUploadResourceInfo(String toscaName){
+        SubCategoryDefinition subCategory = new SubCategoryDefinition();
+        subCategory.setName("Network Elements");
+        CategoryDefinition category = new CategoryDefinition();
+        category.setName("Generic");
+        category.setNormalizedName("generic");
+        category.setIcons(List.of("defaulticon"));
+        category.setNormalizedName("generic");
+        category.addSubCategory(subCategory);
+        List<CategoryDefinition> categories = new ArrayList<>();
+        categories.add(category);
+        super.setCategories(categories);
+        super.setIcon("defaulticon");
+        super.setVendorRelease("1");
+        super.setNormative(false);
+        String[] nodeTemplateName = toscaName.split("\\.");
+        String name =  nodeTemplateName[nodeTemplateName.length - 1];
+        super.setName(name);
+        super.setDescription("A vfc of type " + toscaName);
+        List<String> tags = new ArrayList<>();
+        tags.add(name);
+        super.setTags(tags);
+    }
+}
index 99639f8..9d37624 100644 (file)
@@ -1,7 +1,28 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
 package org.openecomp.sdc.be.model;
 
 import lombok.AllArgsConstructor;
 import lombok.Getter;
+import lombok.Setter;
 
 import java.util.Map;
 
@@ -9,6 +30,7 @@ import java.util.Map;
 @AllArgsConstructor
 public class NodeTypeDefinition {
 
+    @Setter
     private Map.Entry<String, Object> mappedNodeType;
     private NodeTypeMetadata nodeTypeMetadata;
 }
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/NullNodeTypeMetadata.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/NullNodeTypeMetadata.java
new file mode 100644 (file)
index 0000000..6042c9b
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * -
+ *  ============LICENSE_START=======================================================
+ *  Copyright (C) 2022 Nordix Foundation.
+ *  ================================================================================
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ *
+ *  SPDX-License-Identifier: Apache-2.0
+ *  ============LICENSE_END=========================================================
+ */
+
+package org.openecomp.sdc.be.model;
+
+import lombok.NoArgsConstructor;
+
+@NoArgsConstructor
+public class NullNodeTypeMetadata extends NodeTypeMetadata{
+}
index 2073081..31d5253 100644 (file)
@@ -23,7 +23,9 @@ package org.openecomp.sdc.be.model.mapper;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import org.openecomp.sdc.be.model.DefaultUploadResourceInfo;
 import org.openecomp.sdc.be.model.NodeTypeMetadata;
+import org.openecomp.sdc.be.model.NullNodeTypeMetadata;
 import org.openecomp.sdc.be.model.UploadResourceInfo;
 
 /**
@@ -33,6 +35,9 @@ import org.openecomp.sdc.be.model.UploadResourceInfo;
 public class NodeTypeMetadataMapper {
 
     public static UploadResourceInfo mapTo(final NodeTypeMetadata nodeTypeMetadata) {
+        if (nodeTypeMetadata instanceof NullNodeTypeMetadata) {
+            return new DefaultUploadResourceInfo(nodeTypeMetadata.getToscaName());
+        }
         var uploadResourceInfo = new UploadResourceInfo();
         uploadResourceInfo.setName(nodeTypeMetadata.getName());
         uploadResourceInfo.setDescription(nodeTypeMetadata.getDescription());