Support import of updated node types with added attributes 01/130401/9
authorJvD_Ericsson <jeff.van.dam@est.tech>
Fri, 19 Aug 2022 15:11:47 +0000 (16:11 +0100)
committerMichael Morris <michael.morris@est.tech>
Fri, 14 Oct 2022 11:58:46 +0000 (11:58 +0000)
Support addition of new attributes,
new capabilities, new requirements,
and new interfaces

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

catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java
catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogic.java
catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ServiceImportBusinessLogicTest.java
catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar
catalog-be/src/test/resources/node-types/resource-Extcp-template.yml

index aa15d8a..04fe9f5 100644 (file)
@@ -51,6 +51,7 @@ import org.openecomp.sdc.be.datatypes.elements.ListDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition;
 import org.openecomp.sdc.be.datatypes.elements.OperationInputDefinition;
 import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition;
+import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition;
 import org.openecomp.sdc.be.model.InputDefinition;
 import org.openecomp.sdc.be.model.InterfaceDefinition;
 import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder;
@@ -261,6 +262,15 @@ public class InterfaceDefinitionHandler {
                         propertyDef.setName(k);
                         propertyDef.setType(type.getType());
                         propertyDef.setValue(v.toString());
+                        if (type.equals(ToscaPropertyType.LIST)) {
+                            Gson gson = new Gson();
+                            propertyDef.setValue(gson.toJson(v));
+                            PropertyDataDefinition pdd = new PropertyDataDefinition();
+                            pdd.setType("string");
+                            SchemaDefinition sd = new SchemaDefinition();
+                            sd.setProperty(pdd);
+                            propertyDef.setSchema(sd);
+                        }
                         artifactDataDefinition.addProperty(propertyDef);
                     }
                 });
@@ -294,6 +304,9 @@ public class InterfaceDefinitionHandler {
         if (value instanceof Float || value instanceof Double) {
             return ToscaPropertyType.FLOAT;
         }
+        if (value instanceof List) {
+            return ToscaPropertyType.LIST;
+        }
         return null;
     }
     
index 04798ec..7817f2f 100644 (file)
@@ -42,6 +42,7 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
 import java.util.Set;
+import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
@@ -480,14 +481,14 @@ public class ServiceImportBusinessLogic {
                 namesOfNodeTypesToCreate.add(nodeTypeDefinition);
             } else if (result.isLeft()) {
                 Resource latestResource = (Resource) result.left().value();
-                Entry<String, Object> latestMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(),
+                Entry<String, Object> existingMappedToscaTemplate = 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);
+                Map<String, Object> newMappedToscaTemplate = (Map<String, Object>) nodeTypeDefinition.getMappedNodeType().getValue();
+                Map<String, Object> combinedMappedToscaTemplate =
+                    getNewChangesToToscaTemplate(newMappedToscaTemplate, (Map<String, Object>) existingMappedToscaTemplate.getValue());
+                if (!combinedMappedToscaTemplate.equals(existingMappedToscaTemplate.getValue())) {
+                    existingMappedToscaTemplate.setValue(combinedMappedToscaTemplate);
+                    nodeTypeDefinition.setMappedNodeType(existingMappedToscaTemplate);
                     namesOfNodeTypesToCreate.add(nodeTypeDefinition);
                 }
             }
@@ -508,28 +509,111 @@ public class ServiceImportBusinessLogic {
         return eitherNodeTypes.left().value().entrySet().iterator().next();
     }
 
-    private Map<String, Object> getNewChangesToToscaTemplate(Map<String, Object> mappedToscaTemplate, Map<String, Object> latestMappedToscaTemplate) {
-        Map<String, Object> newMappedToscaTemplate = new HashMap<>(latestMappedToscaTemplate);
+    private Map<String, Object> getNewChangesToToscaTemplate(Map<String, Object> newMappedToscaTemplate, 
+                                                             Map<String, Object> existingMappedToscaTemplate) {
+        Map<String, Object> combinedMappedToscaTemplate = new HashMap<>(existingMappedToscaTemplate);
+        combinePropertiesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("properties"),
+                (Map<String, Object>) existingMappedToscaTemplate.get("properties"), combinedMappedToscaTemplate);
+        combineAttributesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("attributes"),
+                (Map<String, Object>) existingMappedToscaTemplate.get("attributes"), combinedMappedToscaTemplate);
+        combineRequirementsIntoToscaTemplate((List<Map<String, Object>>) newMappedToscaTemplate.get("requirements"),
+                (List<Map<String, Object>>) existingMappedToscaTemplate.get("requirements"), combinedMappedToscaTemplate);
+        combineCapabilitiesIntoToscaTemplate((Map<String, Object>) newMappedToscaTemplate.get("capabilities"),
+                (Map<String, Object>) existingMappedToscaTemplate.get("capabilities"), combinedMappedToscaTemplate);
+        combineInterfacesIntoToscaTemplate((Map<String, Map<String, Object>>) newMappedToscaTemplate.get("interfaces"),
+                (Map<String, Map<String, Object>>) existingMappedToscaTemplate.get("interfaces"), combinedMappedToscaTemplate);
+        return combinedMappedToscaTemplate;
+    }
+
+    private void combineInterfacesIntoToscaTemplate(Map<String, Map<String, Object>> newInterfaces,
+                                                    Map<String, Map<String, Object>> existingInterfaces,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Map<String, Object>> combinedInterfaces = combineAdditionalInterfaces(existingInterfaces, newInterfaces);
+        if ((MapUtils.isEmpty(existingInterfaces) && MapUtils.isNotEmpty(combinedInterfaces))
+                || (MapUtils.isNotEmpty(existingInterfaces) && !existingInterfaces.equals(combinedInterfaces))) {
+            combinedMappedToscaTemplate.put("interfaces", combinedInterfaces);
+        }
+    }
+
+    private void combineCapabilitiesIntoToscaTemplate(Map<String, Object> newCapabilities, Map<String, Object> existingCapabilities,
+                                                      Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedCapabilities = combineEntries(newCapabilities, existingCapabilities);
+        if ((MapUtils.isEmpty(existingCapabilities) && MapUtils.isNotEmpty(combinedCapabilities)) ||
+                ( MapUtils.isNotEmpty(existingCapabilities) && !combinedCapabilities.equals(existingCapabilities))) {
+            combinedMappedToscaTemplate.put("capabilities", combinedCapabilities);
+        }
+    }
+
+    private void combineRequirementsIntoToscaTemplate(List<Map<String, Object>> newRequirements, List<Map<String, Object>> existingRequirements,
+                                                      Map<String, Object> combinedMappedToscaTemplate) {
+        List<Map<String, Object>> combinedRequirements = combineAdditionalRequirements(newRequirements, existingRequirements);
+        if ((CollectionUtils.isEmpty(existingRequirements) && CollectionUtils.isNotEmpty(combinedRequirements))
+                || (CollectionUtils.isNotEmpty(existingRequirements) && !combinedRequirements.equals(existingRequirements))) {
+            combinedMappedToscaTemplate.put("requirements", combinedRequirements);
+        }
+    }
+
+    private void combineAttributesIntoToscaTemplate(Map<String, Object> newAttributes, Map<String, Object> existingAttributes,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedAttributes = combineEntries(newAttributes, existingAttributes);
+        if ((MapUtils.isEmpty(existingAttributes) && MapUtils.isNotEmpty(combinedAttributes)) ||
+                ( MapUtils.isNotEmpty(existingAttributes) && !combinedAttributes.equals(existingAttributes))) {
+            combinedMappedToscaTemplate.put("attributes", combinedAttributes);
+        }
+    }
+
+    private void combinePropertiesIntoToscaTemplate(Map<String, Object> newProperties, Map<String, Object> existingProperties,
+                                                    Map<String, Object> combinedMappedToscaTemplate) {
+        Map<String, Object> combinedProperties = combineEntries(newProperties, existingProperties);
+        if ((MapUtils.isEmpty(existingProperties) && MapUtils.isNotEmpty(combinedProperties)) ||
+                (MapUtils.isNotEmpty(existingProperties) && !combinedProperties.equals(existingProperties))) {
+            combinedMappedToscaTemplate.put("properties", combinedProperties);
+        }
+    }
+
+    private Map<String, Map<String, Object>> combineAdditionalInterfaces(Map<String, Map<String, Object>> existingInterfaces,
+                                                                         Map<String, Map<String, Object>> newInterfaces) {
+        if (MapUtils.isEmpty(newInterfaces)) {
+            newInterfaces = new HashMap<>();
+        }
+        Map<String, Map<String, Object>> combinedEntries = new HashMap<>(newInterfaces);
+        if (MapUtils.isEmpty(existingInterfaces)) {
+            return combinedEntries;
+        }
+         existingInterfaces.entrySet().forEach(interfaceDef -> {
+             combinedEntries.entrySet().stream().filter((interFace) -> interFace.getValue().get("type").equals(( interfaceDef.getValue()).get("type")))
+                    .findFirst().ifPresentOrElse((interFace) -> {
+                        interFace.getValue().putAll(interfaceDef.getValue());
+                    }, () -> {
+                        combinedEntries.put(interfaceDef.getKey(), interfaceDef.getValue());
+                    });
+        });
+        return combinedEntries;
+    }
 
-        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);
+    private List<Map<String, Object>> combineAdditionalRequirements(List<Map<String, Object>> newReqs, List<Map<String, Object>> existingResourceReqs) {
+        if (CollectionUtils.isEmpty(newReqs)) {
+            newReqs = new ArrayList<>();
+        }
+        Set<Map<String, Object>> combinedReqs = new TreeSet<>((map1, map2) ->
+            map1.keySet().equals(map2.keySet()) ? 0 : map1.keySet().iterator().next().compareTo(map2.keySet().iterator().next()));
+        combinedReqs.addAll(existingResourceReqs);
+        if (CollectionUtils.isEmpty(newReqs)) {
+            return new ArrayList<>(combinedReqs);
         }
-        return newMappedToscaTemplate;
+        combinedReqs.addAll(newReqs);
+        return new ArrayList<>(combinedReqs);
     }
 
-    private Map<String, Object> combinedEntries(Map<String, Object> firstMap, Map<String, Object> secondMap) {
-        if (MapUtils.isEmpty(firstMap)) {
-            firstMap = new HashMap<>();
+    private Map<String, Object> combineEntries(Map<String, Object> newMap, Map<String, Object> existingMap) {
+        if (MapUtils.isEmpty(newMap)) {
+            newMap = new HashMap<>();
         }
-        Map<String, Object> combinedEntries = new HashMap<>(firstMap);
-        if (MapUtils.isEmpty(secondMap)) {
+        Map<String, Object> combinedEntries = new HashMap<>(newMap);
+        if (MapUtils.isEmpty(existingMap)) {
             return combinedEntries;
         }
-        combinedEntries.putAll(secondMap);
+        combinedEntries.putAll(existingMap);
         return combinedEntries;
     }
 
index f665669..83bcf81 100644 (file)
@@ -318,6 +318,10 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest
         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());
+        Assertions.assertNull(newUpdatedNodeType.get("attributes"));
+        assertEquals(3, ((List<Map<String, Object>>) newUpdatedNodeType.get("requirements")).size());
+        assertEquals(1, ((Map<String, Object>) newUpdatedNodeType.get("capabilities")).size());
+        assertEquals(2, ((Map<String, Object>) newUpdatedNodeType.get("interfaces")).size());
 
         ArgumentCaptor<String> interfaceTypes = ArgumentCaptor.forClass(String.class);
         verify(interfaceLifecycleTypeImportManager).createLifecycleTypes(interfaceTypes.capture(), any(), anyBoolean());
index de7d71f..5c990c9 100644 (file)
Binary files a/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar and b/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar differ
index 4302a12..1dac9a0 100644 (file)
@@ -85,11 +85,12 @@ node_types:
         - 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
+    interfaces:
+      Vnflcm:
+        type: tosca.interfaces.nfv.Vnflcm
+        heal:
+          description: ASDASDAS
+          implementation: Artifacts/Deployment/WORKFLOW/BPMN/ASDWASDW
+          inputs:
+            sd: original
+            ADWA: original
\ No newline at end of file