From 680d8a6f9bd8f2be953f835c9fff6ac3ebfeb1c3 Mon Sep 17 00:00:00 2001 From: JvD_Ericsson Date: Fri, 19 Aug 2022 16:11:47 +0100 Subject: [PATCH] Support import of updated node types with added attributes Support addition of new attributes, new capabilities, new requirements, and new interfaces Issue-ID: SDC-4142 Signed-off-by: JvD_Ericsson Change-Id: I987fdf6b0e7dae275fcc6ac43f3dd7aa21628f4a --- .../impl/InterfaceDefinitionHandler.java | 13 +++ .../impl/ServiceImportBusinessLogic.java | 128 +++++++++++++++++---- .../impl/ServiceImportBusinessLogicTest.java | 4 + .../resources/csars/service-Ser09080002-csar.csar | Bin 63966 -> 63979 bytes .../node-types/resource-Extcp-template.yml | 17 +-- 5 files changed, 132 insertions(+), 30 deletions(-) diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java index aa15d8ae8d..04fe9f54b6 100644 --- a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceDefinitionHandler.java @@ -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; } 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 04798ec40a..7817f2f261 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 @@ -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 latestMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(), + Entry existingMappedToscaTemplate = getResourceToscaTemplate(latestResource.getUniqueId(), latestResource.getToscaArtifacts().get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE), csarInfo.getModifier().getUserId()); - Map mappedToscaTemplate = (Map) nodeTypeDefinition.getMappedNodeType().getValue(); - Map newMappedToscaTemplate = - getNewChangesToToscaTemplate(mappedToscaTemplate, (Map) latestMappedToscaTemplate.getValue()); - if (!newMappedToscaTemplate.equals(latestMappedToscaTemplate.getValue())) { - latestMappedToscaTemplate.setValue(newMappedToscaTemplate); - nodeTypeDefinition.setMappedNodeType(latestMappedToscaTemplate); + Map newMappedToscaTemplate = (Map) nodeTypeDefinition.getMappedNodeType().getValue(); + Map combinedMappedToscaTemplate = + getNewChangesToToscaTemplate(newMappedToscaTemplate, (Map) 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 getNewChangesToToscaTemplate(Map mappedToscaTemplate, Map latestMappedToscaTemplate) { - Map newMappedToscaTemplate = new HashMap<>(latestMappedToscaTemplate); + private Map getNewChangesToToscaTemplate(Map newMappedToscaTemplate, + Map existingMappedToscaTemplate) { + Map combinedMappedToscaTemplate = new HashMap<>(existingMappedToscaTemplate); + combinePropertiesIntoToscaTemplate((Map) newMappedToscaTemplate.get("properties"), + (Map) existingMappedToscaTemplate.get("properties"), combinedMappedToscaTemplate); + combineAttributesIntoToscaTemplate((Map) newMappedToscaTemplate.get("attributes"), + (Map) existingMappedToscaTemplate.get("attributes"), combinedMappedToscaTemplate); + combineRequirementsIntoToscaTemplate((List>) newMappedToscaTemplate.get("requirements"), + (List>) existingMappedToscaTemplate.get("requirements"), combinedMappedToscaTemplate); + combineCapabilitiesIntoToscaTemplate((Map) newMappedToscaTemplate.get("capabilities"), + (Map) existingMappedToscaTemplate.get("capabilities"), combinedMappedToscaTemplate); + combineInterfacesIntoToscaTemplate((Map>) newMappedToscaTemplate.get("interfaces"), + (Map>) existingMappedToscaTemplate.get("interfaces"), combinedMappedToscaTemplate); + return combinedMappedToscaTemplate; + } + + private void combineInterfacesIntoToscaTemplate(Map> newInterfaces, + Map> existingInterfaces, + Map combinedMappedToscaTemplate) { + Map> 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 newCapabilities, Map existingCapabilities, + Map combinedMappedToscaTemplate) { + Map 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> newRequirements, List> existingRequirements, + Map combinedMappedToscaTemplate) { + List> 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 newAttributes, Map existingAttributes, + Map combinedMappedToscaTemplate) { + Map 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 newProperties, Map existingProperties, + Map combinedMappedToscaTemplate) { + Map combinedProperties = combineEntries(newProperties, existingProperties); + if ((MapUtils.isEmpty(existingProperties) && MapUtils.isNotEmpty(combinedProperties)) || + (MapUtils.isNotEmpty(existingProperties) && !combinedProperties.equals(existingProperties))) { + combinedMappedToscaTemplate.put("properties", combinedProperties); + } + } + + private Map> combineAdditionalInterfaces(Map> existingInterfaces, + Map> newInterfaces) { + if (MapUtils.isEmpty(newInterfaces)) { + newInterfaces = new HashMap<>(); + } + Map> 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 properties = (Map) mappedToscaTemplate.get("properties"); - Map latestProperties = (Map) latestMappedToscaTemplate.get("properties"); - Map allProperties = combinedEntries(properties, latestProperties); - if ((MapUtils.isEmpty(latestProperties) && MapUtils.isNotEmpty(allProperties)) || - (MapUtils.isNotEmpty(latestProperties) && !allProperties.equals(latestProperties))) { - newMappedToscaTemplate.put("properties", allProperties); + private List> combineAdditionalRequirements(List> newReqs, List> existingResourceReqs) { + if (CollectionUtils.isEmpty(newReqs)) { + newReqs = new ArrayList<>(); + } + Set> 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 combinedEntries(Map firstMap, Map secondMap) { - if (MapUtils.isEmpty(firstMap)) { - firstMap = new HashMap<>(); + private Map combineEntries(Map newMap, Map existingMap) { + if (MapUtils.isEmpty(newMap)) { + newMap = new HashMap<>(); } - Map combinedEntries = new HashMap<>(firstMap); - if (MapUtils.isEmpty(secondMap)) { + Map combinedEntries = new HashMap<>(newMap); + if (MapUtils.isEmpty(existingMap)) { return combinedEntries; } - combinedEntries.putAll(secondMap); + combinedEntries.putAll(existingMap); return combinedEntries; } 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 f6656693d9..83bcf81178 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 @@ -318,6 +318,10 @@ class ServiceImportBusinessLogicTest extends ServiceImportBussinessLogicBaseTest Map nodeTypesMap = nodeTypes.getValue(); Map newUpdatedNodeType = (Map) nodeTypesMap.get(updatedNodeType); assertEquals(8, ((Map) newUpdatedNodeType.get("properties")).size()); + Assertions.assertNull(newUpdatedNodeType.get("attributes")); + assertEquals(3, ((List>) newUpdatedNodeType.get("requirements")).size()); + assertEquals(1, ((Map) newUpdatedNodeType.get("capabilities")).size()); + assertEquals(2, ((Map) newUpdatedNodeType.get("interfaces")).size()); ArgumentCaptor interfaceTypes = ArgumentCaptor.forClass(String.class); verify(interfaceLifecycleTypeImportManager).createLifecycleTypes(interfaceTypes.capture(), any(), anyBoolean()); diff --git a/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar b/catalog-be/src/test/resources/csars/service-Ser09080002-csar.csar index de7d71fc376812e426fb9ec3f26faa775cefc1b4..5c990c98bda26ea1c4cdf6ed4a3519bd4c175766 100644 GIT binary patch delta 1130 zcmV-w1eN>V^8@Si1F(nG76SkP2mtFyL{&^n_Plrl000LI001YGao8A>wbT-S)m7V$ z(=ZTy->>i!mxs6wDOr)Xg#uau-D>IXK1OalZ7m!-*ltVzo^jILHZ2H&K=dNTGv|!Y zTA+%BDLo79SE)xvaMSR$(eLk#id%ZLSG$S#9P$fIESGLC{* zW0699Knj^kdU|E+?zSBIM~dH!j<|K8z5JUCkygMD+QT1lDQVjktMT0+@S!% zq$JvHz>qg{WE-&qvNAfySh?mPeHIyWu-4{~koTYvlA+C$6H@MJx62lPF$1^P<_mc% zAqV9w`VCmUH5uH4;@TwSW_C3v&lbLT&j;>Xkiaa44(S-bdp?dzOb7DG>zZxzC19|p zPcN|k+BlnB1Vo_=9|(R{LPAm*=pmQr^i4t8eSkL}{TVCRQb_D_AJW>JPzEF`hhZa% zF1F{W!E2+peU!H}?m|m{k@dH%Z571lkT$}#SyNpA_EYBtt&2yqf`XrcDoWKzp88H6 z=ag2ZxYgPr;zF%ki8{-+#sG#tLM!;V^L#gZeRDUPzMa;# zc4QBA_uC=vl*n(!ma?gMZ+vTJ*Vd=nh3>m+lpRx-=`=b?_*qN!T#Xa#MP+%UCRykgP3=YxH@6?&eY|-Xy`F!XjWEQ6|Nlh3<>$m-A^)8A6cqnI^?!Cuac20>&${M7 zo4KMj?>kTfO9KRxy!INiblCA7C_e)f0{{RB0P9FZRZL6vym$iu00#>I04D$>00000 z0000WfV6>v)RQ6g8k4xx4;^o7n9HTS^}WolOgpNlh5}elZf{elX&gkoFIM#a2sm z+c*rq`&Z!9$3Ysqc9f}asgv1eCUHF(Csz$k!ZN26sgjgi|NDY^S#ncnx7pcEE;jH1 z`0yZLZyaZ-z^&BMOQT)7N9*Xr9DJp6GA|US2bQaJl1@iCdM21>^AUj5duAom{_*kl zdJZ3_rJ1K9Fb$JNs%NwXg#j0W0 z$zp&VC>n5PO*ur>l15#B7$x~h$W~TCLJnz1+}JEO1@(cOyolT4#k`0y%s}m>Zlp*< zC!0Bq>ry-z;~U7oHz@#xB~JEOIU4;UwfL=+ww{Al+)j>?&Uc~#7byrYx8w?LSJ3xC zi2xC(r>_2M)Pj<?VR^`7x(%KH1}-(M|&2|*L?fH@~K{qhj>dEt-6Dy8j6bvm1P#W&5uW}_`8 zT9e^GolkLDnY_S%XRnxk{gVh@UR9RYK8`0M@WS&*Jhhv!14JPJP=I4mtm`EaHd19ywJ}_Vj>6}gt2KC}GfiL5zd2)Rvz>CMJ%}0F=gEiF zSy=_Lbq9d9XZRE*MOPd8lx)51 z2RCa;o4-RD&P%E^(di9f1moW4$K|IlkIUrS?3w1d+6)TF%|TI2ior5%$Mo#at3 zz23w}u$R`COns7C3|{9SaqCh&Jezz=Ceh02zWb(bZHDCUr2hKfFb|Rb zka;jYGN&IF2=xg4|0#rFIo&ngZ<)P{pYC3f?N75m*bg3)KJ^S7`h5c#j{^VzvkL$K zCjbBd0000000000004s2ld#JglaTfglREVflhgJZ0#?|Qu*(;dPxuFu4fjw2ciEG$ z%NLVR_y?1H_eKJ`+>@}&7n4u;B9s32I0Codld#JdlTY|i0s51m_+tY4>64-ODw8ky uQUT+Wg84=xr||#)V{>70E^TFWVNgp21^@s602Tli0LBLZ00Qy=0001(K^$8E 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 index 4302a129d7..1dac9a0e83 100644 --- a/catalog-be/src/test/resources/node-types/resource-Extcp-template.yml +++ b/catalog-be/src/test/resources/node-types/resource-Extcp-template.yml @@ -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 -- 2.16.6