From d6f0e5ba491d94cf71486b86a14a17bb411a2a4b Mon Sep 17 00:00:00 2001 From: Ester Rotstein Date: Sun, 6 Aug 2017 10:04:42 +0300 Subject: [PATCH] [SDC-182] support nested properties with function Change-Id: I7c7dda4940010bd018880f76eb61eeb2de6d4fcc Signed-off-by: Ester Rotstein --- .../sdc/tosca/parser/impl/SdcCsarHelperImpl.java | 13 +----- .../sdc/impl/SdcToscaParserBasicTest.java | 2 - .../sdc/impl/ToscaParserNodeTemplateTest.java | 52 ++++++++++++--------- .../csars/service-Ipassignservice-csar.csar | Bin 49975 -> 50084 bytes 4 files changed, 31 insertions(+), 36 deletions(-) diff --git a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java index 9b40416..bafdee2 100644 --- a/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java +++ b/src/main/java/org/openecomp/sdc/tosca/parser/impl/SdcCsarHelperImpl.java @@ -736,22 +736,13 @@ public class SdcCsarHelperImpl implements ISdcCsarHelper { if (property instanceof Map) { for (Map.Entry item: ((Map) property).entrySet()) { - if (item.getKey().equals("get_input")) { - String itemToStr = item.getKey() + ":" + item.getValue().toString(); - filterProperties(itemToStr, path, filterType, pattern, filterMap); - } else { - path += PATH_DELIMITER + item.getKey(); - filterProperties(item.getValue(), path, filterType, pattern, filterMap); - } + String itemPath = path + PATH_DELIMITER + item.getKey(); + filterProperties(item.getValue(), itemPath, filterType, pattern, filterMap); } } else if (property instanceof List) { for (Object item: (List)property) { filterProperties(item, path, filterType, pattern, filterMap); } - } else if (property instanceof Function) { - if (filterType.isMatch(property.toString(), pattern)) { - filterMap.put(path, property.toString()); - } } else { if (filterType.isMatch(property.toString(), pattern)) { filterMap.put(path, property.toString()); diff --git a/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java b/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java index 817ac92..28dd376 100644 --- a/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java +++ b/src/test/java/org/openecomp/sdc/impl/SdcToscaParserBasicTest.java @@ -24,7 +24,6 @@ public abstract class SdcToscaParserBasicTest { static ISdcCsarHelper rainyCsarHelperSingleVf; static ISdcCsarHelper rainyCsarHelperMultiVfs; static ISdcCsarHelper fdntCsarHelper; - static ISdcCsarHelper complexCps; static ISdcCsarHelper fdntCsarHelperWithInputs; static ISdcCsarHelper nfodCsarHlper; static ISdcCsarHelper ipAssignCsarHelper; @@ -38,7 +37,6 @@ public abstract class SdcToscaParserBasicTest { fdntCsarHelper = getCsarHelper("csars/service-sunny-flow.csar"); rainyCsarHelperMultiVfs = getCsarHelper("csars/service-ServiceFdnt-csar-rainy.csar"); rainyCsarHelperSingleVf = getCsarHelper("csars/service-ServiceFdnt-csar.csar"); - complexCps = getCsarHelper("csars/service-consolidated-props-csar.csar"); fdntCsarHelperWithInputs = getCsarHelper("csars/service-ServiceFdnt-with-get-input.csar"); nfodCsarHlper = getCsarHelper("csars/service-NfodService-csar.csar"); ipAssignCsarHelper = getCsarHelper("csars/service-Ipassignservice-csar.csar"); diff --git a/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java b/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java index 4ab9af3..e31828c 100644 --- a/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java +++ b/src/test/java/org/openecomp/sdc/impl/ToscaParserNodeTemplateTest.java @@ -66,6 +66,12 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { assertEquals(null, fdntCsarHelperWithInputs.getNodeTemplatePropertyLeafValue(serviceVfList.get(1), "target_network_role")); } + @Test + public void testNodeTemplateNestedFunctionProperty() throws SdcToscaParserException { + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); + assertEquals(null, ipAssignCsarHelper.getNodeTemplatePropertyLeafValue(vfcs.get(0), "port_pd01_port_ip_requirements#ip_count_required#count")); + } + @Test public void testNodeTemplateNestedProperty() throws SdcToscaParserException { List serviceVlList = fdntCsarHelper.getServiceVlList(); @@ -352,7 +358,7 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { assertEquals("subnet_role_4", firstIpRequirements.get("subnet_role")); assertEquals(4, firstIpRequirements.get("ip_version")); assertEquals(true, ((Map) firstIpRequirements.get("ip_count_required")).get("is_required")); - assertEquals(4, ((Map) firstIpRequirements.get("ip_count_required")).get("count")); + assertEquals("get_input:node_count", ((Map) firstIpRequirements.get("ip_count_required")).get("count").toString()); assertEquals(false, ((Map)((Map)pd01.get("mac_requirements")).get("mac_count_required")).get("is_required")); assertEquals("test_subnetpoolid", pd01.get("subnetpoolid")); assertEquals("oam", pd01.get("network_role_tag")); @@ -363,7 +369,6 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { assertTrue(isChecked); } - @Test public void testGetCpPropertiesFromVfcForNullVFC() { Map> cps = ipAssignCsarHelper.getCpPropertiesFromVfcAsObject(null); @@ -395,17 +400,18 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { //region filterNodeTemplatePropertiesByValue @Test public void testFilterNodeTemplatePropertiesByContains() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); boolean isChecked = false; for (NodeTemplate vfc: vfcs) { - if(vfc.getName().equalsIgnoreCase("abstract_ddc")) + if(vfc.getName().equalsIgnoreCase("abstract_pd_server")) { isChecked = true; - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfc, FilterType.CONTAINS, "get_input"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfc, FilterType.CONTAINS, "get_input"); - assertEquals(16, filteredInputs.size()); - assertEquals("get_input:vnf_id", filteredInputs.get("compute_ddc_metadata#vf_module_id#vnf_id")); - assertEquals("get_input:[ddc_int_imbl_v6_ips, 3]", filteredInputs.get("port_ddc_int_imbl__port_fixed_ips#ip_address")); + assertEquals(7, filteredInputs.size()); + assertEquals("get_input:availabilityzone_name", filteredInputs.get("compute_pd_server_availability_zone")); + assertEquals("get_input:[pd_server_names, 0]", filteredInputs.get("compute_pd_server_name")); + assertEquals("get_input:node_count", filteredInputs.get("port_pd01_port_ip_requirements#ip_count_required#count")); break; } @@ -416,25 +422,25 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { @Test public void testFilterNodeTemplatePropertiesByDummyContains() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfcs.get(0), FilterType.CONTAINS, "dummy"); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfcs.get(0), FilterType.CONTAINS, "dummy"); assertNotNull(filteredInputs); assertEquals(0, filteredInputs.size()); } @Test public void testFilterNodeTemplatePropertiesByEquals() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); boolean isChecked = false; for (NodeTemplate vfc: vfcs) { - if(vfc.getName().equalsIgnoreCase("abstract_ddc")) + if(vfc.getName().equalsIgnoreCase("abstract_pd_server")) { isChecked = true; - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfc, FilterType.EQUALS, "ddc"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfc, FilterType.EQUALS, "oam"); assertEquals(2, filteredInputs.size()); - assertEquals("ddc", filteredInputs.get("vm_type_tag")); - assertEquals("ddc", filteredInputs.get("nfc_naming_code")); + assertEquals("oam", filteredInputs.get("port_pd02_port_network_role_tag")); + assertEquals("oam", filteredInputs.get("port_pd01_port_network_role_tag")); break; } @@ -444,31 +450,31 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { @Test public void testFilterNodeTemplatePropertiesByDummyEquals() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfcs.get(0), FilterType.EQUALS, "dummy"); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfcs.get(0), FilterType.EQUALS, "dummy"); assertNotNull(filteredInputs); assertEquals(0, filteredInputs.size()); } @Test public void testFilterNodeTemplatePropertiesByNullFilterType() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfcs.get(11), null, "ddc"); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfcs.get(0), null, "ddc"); assertNotNull(filteredInputs); assertEquals(0, filteredInputs.size()); } @Test public void testFilterNodeTemplatePropertiesByNullPattern() { - List vfcs = complexCps.getVfcListByVf("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(vfcs.get(11), FilterType.EQUALS, null); + List vfcs = ipAssignCsarHelper.getVfcListByVf("b5190df2-7880-4d6f-836f-56ab17e1b85b"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(vfcs.get(0), FilterType.EQUALS, null); assertNotNull(filteredInputs); assertEquals(0, filteredInputs.size()); } @Test public void testFilterNodeTemplatePropertiesByNullVfc() { - Map filteredInputs = complexCps.filterNodeTemplatePropertiesByValue(null, FilterType.EQUALS, "ddc"); + Map filteredInputs = ipAssignCsarHelper.filterNodeTemplatePropertiesByValue(null, FilterType.EQUALS, "ddc"); assertNotNull(filteredInputs); assertEquals(0, filteredInputs.size()); } @@ -527,7 +533,7 @@ public class ToscaParserNodeTemplateTest extends SdcToscaParserBasicTest { @Test public void testGetVnfConfigByNonFoundVNF() { - NodeTemplate vnfConfig = complexCps.getVnfConfig("f999e2ca-72c0-42d3-9b11-13f2122fb8ef"); + NodeTemplate vnfConfig = ipAssignCsarHelper.getVnfConfig("b5190df2-7880-4d6f-836f-56ab17e1b85b"); assertNull(vnfConfig); } diff --git a/src/test/resources/csars/service-Ipassignservice-csar.csar b/src/test/resources/csars/service-Ipassignservice-csar.csar index 050745737ec7855863b85fe96914eb3768dafca8..abdcd3e90af41185b108d2f2ab1c7deccbac65c3 100644 GIT binary patch delta 3862 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