From 43c9e83b3cc9b3dfaf55f08fc25813a77a4f2784 Mon Sep 17 00:00:00 2001 From: "Agarwal, Ruchira (ra1926)" Date: Wed, 28 Aug 2019 01:48:21 +0000 Subject: [PATCH] sync restapi-call-node with ecomp sync onap rest-api-call-node with ecomp Issue-ID: CCSDK-1659 Signed-off-by: Agarwal, Ruchira (ra1926) Change-Id: I08b0b8332b68a22710cd412997f3763de4b5b8d3 --- .../sli/plugins/restapicall/HttpResponse.java | 7 +- .../ccsdk/sli/plugins/restapicall/JsonParser.java | 12 ++- .../ccsdk/sli/plugins/restapicall/RetryPolicy.java | 43 ++++---- .../ccsdk/sli/plugins/restapicall/XmlJsonUtil.java | 119 +++++++++++++-------- .../ccsdk/sli/plugins/restapicall/XmlParser.java | 11 +- .../sli/plugins/restapicall/TestXmlJsonUtil.java | 59 ++++++++++ .../provider/src/test/resources/test-template.json | 1 + 7 files changed, 181 insertions(+), 71 deletions(-) diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/HttpResponse.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/HttpResponse.java index 66993aab..57408952 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/HttpResponse.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/HttpResponse.java @@ -8,9 +8,9 @@ * 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. @@ -21,6 +21,8 @@ package org.onap.ccsdk.sli.plugins.restapicall; +import java.util.List; +import java.util.Map; import javax.ws.rs.core.MultivaluedMap; public class HttpResponse { @@ -28,4 +30,5 @@ public class HttpResponse { public String message; public String body; public MultivaluedMap headers; + public Map> headers2; } diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/JsonParser.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/JsonParser.java index 189ddde3..910baf52 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/JsonParser.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/JsonParser.java @@ -8,7 +8,7 @@ * 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 @@ -50,7 +50,15 @@ public final class JsonParser { checkNotNull(s, "Input should not be null."); try { - JSONObject json = new JSONObject(s); + JSONObject json = null; + //support top level list in json response + if (s.startsWith("[")) { + JSONArray jsonArr = new JSONArray(s); + json = jsonArr.getJSONObject(0); + } else { + json = new JSONObject(s); + } + Map wm = new HashMap<>(); Iterator ii = json.keys(); while (ii.hasNext()) { diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicy.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicy.java index 65684d93..8d5143be 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicy.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicy.java @@ -21,41 +21,44 @@ */ package org.onap.ccsdk.sli.plugins.restapicall; + public class RetryPolicy { private String[] hostnames; private Integer maximumRetries; - private int position; - private int retryCount; + public RetryPolicy(String[] hostnames, Integer maximumRetries) { - this.hostnames = hostnames; - this.maximumRetries = maximumRetries; - - this.position = 0; - - this.retryCount = 0; + this.hostnames = hostnames; + this.maximumRetries = maximumRetries; + this.position = 0; + this.retryCount = 0; + } + public Integer getMaximumRetries() { - return maximumRetries; + return maximumRetries; } + public int getRetryCount() { - return retryCount; + return retryCount; } + public Boolean shouldRetry() { - return retryCount < maximumRetries + 1; + return retryCount < maximumRetries + 1; } + public String getRetryMessage() { - return retryCount + " retry attempts were made out of " + maximumRetries + " maximum retry attempts."; + return retryCount + " retry attempts were made out of " + maximumRetries + " maximum retry attempts."; } public String getNextHostName() throws RetryException { - retryCount++; - position++; - - if (position > hostnames.length - 1) { - position = 0; - } - return hostnames[position]; + retryCount++; + position++; + if (position > hostnames.length - 1) { + position = 0; } -} \ No newline at end of file + return hostnames[position]; + } + +} diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlJsonUtil.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlJsonUtil.java index 4712b429..bc6afd84 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlJsonUtil.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlJsonUtil.java @@ -8,9 +8,9 @@ * 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. @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,38 +66,45 @@ public final class XmlJsonUtil { private static Object createStructure(Map flatmap, String var) { if (flatmap.containsKey(var)) { - if (var.endsWith("_length") || var.endsWith("].key")) + if (var.endsWith("_length") || var.endsWith("].key")) { return null; + } return flatmap.get(var); } Map mm = new HashMap<>(); - for (String k : flatmap.keySet()) + for (String k : flatmap.keySet()) { if (k.startsWith(var + ".")) { int i1 = k.indexOf('.', var.length() + 1); int i2 = k.indexOf('[', var.length() + 1); int i3 = k.length(); - if (i1 > 0 && i1 < i3) + if (i1 > 0 && i1 < i3) { i3 = i1; - if (i2 > 0 && i2 < i3) + } + if (i2 > 0 && i2 < i3) { i3 = i2; + } String k1 = k.substring(var.length() + 1, i3); String var1 = k.substring(0, i3); if (!mm.containsKey(k1)) { Object str = createStructure(flatmap, var1); - if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) + if (str != null && (!(str instanceof String) || ((String) str).trim().length() > 0)) { mm.put(k1, str); + } } } - if (!mm.isEmpty()) + } + if (!mm.isEmpty()) { return mm; + } boolean arrayFound = false; - for (String k : flatmap.keySet()) + for (String k : flatmap.keySet()) { if (k.startsWith(var + "[")) { arrayFound = true; break; } + } if (arrayFound) { List ll = new ArrayList<>(); @@ -115,13 +121,15 @@ public final class XmlJsonUtil { for (int i = 0; i < length; i++) { Object v = createStructure(flatmap, var + '[' + i + ']'); - if (v == null) + if (v == null) { break; + } ll.add(v); } - if (!ll.isEmpty()) + if (!ll.isEmpty()) { return ll; + } } return null; @@ -129,16 +137,18 @@ public final class XmlJsonUtil { @SuppressWarnings("unchecked") private static String generateXml(Object o, int indent, boolean escape) { - if (o == null) + if (o == null) { return null; + } - if (o instanceof String) - return escape ? escapeXml((String) o) : (String) o;; + if (o instanceof String) { + return escape ? escapeXml((String) o) : (String) o; + }; if (o instanceof Map) { StringBuilder ss = new StringBuilder(); Map mm = (Map) o; - for (Map.Entry entry: mm.entrySet()) { + for (Map.Entry entry : mm.entrySet()) { Object v = entry.getValue(); String key = entry.getKey(); if (v instanceof String) { @@ -164,10 +174,13 @@ public final class XmlJsonUtil { return null; } - private static String generateJson(Object o, boolean escape, boolean quotes) { - if (o == null) + if (o == null) { return null; + } + if (o instanceof String && ((String) o).length() == 0) { + return null; + } StringBuilder ss = new StringBuilder(); generateJson(ss, o, 0, false, escape, quotes); @@ -178,8 +191,9 @@ public final class XmlJsonUtil { private static void generateJson(StringBuilder ss, Object o, int indent, boolean padFirst, boolean escape, boolean quotes) { if (o instanceof String) { String s = escape ? escapeJson((String) o) : (String) o; - if (padFirst) + if (padFirst) { ss.append(pad(indent)); + } if (quotes) { ss.append('"').append(s).append('"'); } else { @@ -191,14 +205,16 @@ public final class XmlJsonUtil { if (o instanceof Map) { Map mm = (Map) o; - if (padFirst) + if (padFirst) { ss.append(pad(indent)); + } ss.append("{\n"); boolean first = true; for (Map.Entry entry : mm.entrySet()) { - if (!first) + if (!first) { ss.append(",\n"); + } first = false; Object v = entry.getValue(); String key = entry.getKey(); @@ -215,14 +231,16 @@ public final class XmlJsonUtil { if (o instanceof List) { List ll = (List) o; - if (padFirst) + if (padFirst) { ss.append(pad(indent)); + } ss.append("[\n"); boolean first = true; for (Object o1 : ll) { - if (!first) + if (!first) { ss.append(",\n"); + } first = false; generateJson(ss, o1, indent + 1, true, escape, quotes); @@ -241,14 +259,16 @@ public final class XmlJsonUtil { int i11 = s.indexOf('}', k); int i12 = s.indexOf(']', k); int i1 = -1; - if (i11 < 0) + if (i11 < 0) { i1 = i12; - else if (i12 < 0) + } else if (i12 < 0) { i1 = i11; - else + } else { i1 = i11 < i12 ? i11 : i12; - if (i1 < 0) + } + if (i1 < 0) { break; + } int i2 = s.lastIndexOf(',', i1); if (i2 < 0) { @@ -282,15 +302,14 @@ public final class XmlJsonUtil { if (i11 < 0) { i1 = i12; curly = false; - } else if (i12 < 0) + } else if (i12 < 0) { i1 = i11; - else - if (i11 < i12) - i1 = i11; - else { - i1 = i12; - curly = false; - } + } else if (i11 < i12) { + i1 = i11; + } else { + i1 = i12; + curly = false; + } if (i1 >= 0) { int i2 = curly ? s.indexOf('}', i1) : s.indexOf(']', i1); @@ -298,25 +317,31 @@ public final class XmlJsonUtil { String value = s.substring(i1 + 1, i2); if (value.trim().length() == 0) { int i4 = s.lastIndexOf('\n', i1); - if (i4 < 0) + if (i4 < 0) { i4 = 0; + } int i5 = s.indexOf('\n', i2); - if (i5 < 0) + if (i5 < 0) { i5 = s.length(); + } + /*If template mandates empty construct to be present, those should not be removed.*/ - if ((template != null) && template.contains(s.substring(i4))) { + if (template != null && template.contains(s.substring(i4))) { k = i1 + 1; } else { s = s.substring(0, i4) + s.substring(i5); k = 0; } - } else + } else { k = i1 + 1; - } else + } + } else { break; - } else + } + } else { break; + } } return s; @@ -326,8 +351,9 @@ public final class XmlJsonUtil { int k = 0; while (k < s.length()) { int i1 = s.indexOf('<', k); - if (i1 < 0 || i1 == s.length() - 1) + if (i1 < 0 || i1 == s.length() - 1) { break; + } char c1 = s.charAt(i1 + 1); if (c1 == '?' || c1 == '!') { @@ -355,11 +381,13 @@ public final class XmlJsonUtil { } int i4 = s.lastIndexOf('\n', i1); - if (i4 < 0) + if (i4 < 0) { i4 = 0; + } int i5 = s.indexOf('\n', i3); - if (i5 < 0) + if (i5 < 0) { i5 = s.length(); + } s = s.substring(0, i4) + s.substring(i5); k = 0; @@ -385,8 +413,9 @@ public final class XmlJsonUtil { private static String pad(int n) { StringBuilder s = new StringBuilder(); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { s.append(Character.toString('\t')); + } return s.toString(); } } diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlParser.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlParser.java index cf6af66f..42e9e57a 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlParser.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/XmlParser.java @@ -35,6 +35,7 @@ import java.util.Set; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import javax.xml.XMLConstants; import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.slf4j.Logger; @@ -42,6 +43,7 @@ import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.XMLReader; public final class XmlParser { @@ -58,10 +60,15 @@ public final class XmlParser { Handler handler = new Handler(listNameList); try { - SAXParserFactory factory = SAXParserFactory.newInstance(); - SAXParser saxParser = factory.newSAXParser(); + SAXParserFactory spf = SAXParserFactory.newInstance(); + spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + spf.setFeature("http://xml.org/sax/features/external-general-entities", false); + spf.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + spf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); InputStream in = new ByteArrayInputStream(s.getBytes()); + SAXParser saxParser = spf.newSAXParser(); saxParser.parse(in, handler); + } catch (ParserConfigurationException | IOException | SAXException | NumberFormatException e) { throw new SvcLogicException("Unable to convert XML to properties" + e.getLocalizedMessage(), e); } diff --git a/restapi-call-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/restapicall/TestXmlJsonUtil.java b/restapi-call-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/restapicall/TestXmlJsonUtil.java index 9812f2a1..ac6d3b78 100644 --- a/restapi-call-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/restapicall/TestXmlJsonUtil.java +++ b/restapi-call-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/restapicall/TestXmlJsonUtil.java @@ -152,6 +152,65 @@ public class TestXmlJsonUtil { log.info(ss); } + public void testRemoveEmptyStructJson1() { + String xmlin = "{\n" + + " \"policyName\" : \"default-domain.ECOM_Tenant_DND.ECOM_Tenant_DND_mtn6_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_landing-network-role_policy_05\",\n" + + " \"policyConfigType\": \"MicroService\",\n" + + " \"ecompName\": \"SDNC\",\n" + + " \"configBody\": \"{\\\"service\\\": \\\"NetworkPolicy\\\"," + + "\\\"location\\\": \\\"Search\\\",\\\"uuid\\\": \\\"Search\\\"," + + "\\\"policyName\\\": \\\"default-domain.ECOM_Tenant_DND.ECOM_Tenant_DND_mtn6_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_landing-network-role_policy_05\\\"," + + "\\\"description\\\": \\\"default-domain.ECOM_Tenant_DND.ECOM_Tenant_DND_mtn6_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_landing-network-role_policy_05\\\",\\\"configName\\\": \\\"Search\\\"," + + "\\\"templateVersion\\\": \\\"1607\\\",\\\"version\\\": \\\"1.3.0.1\\\"," + + "\\\"priority\\\": \\\"2\\\",\\\"policyScope\\\": \\\"SDNC\\\",\\\"riskType\\\": \\\"low\\\"," + + "\\\"riskLevel\\\": \\\"2\\\",\\\"guard\\\": \\\"True\\\",\\\"content\\\":{ " + + "\\\"network-policy\\\": { \\\"display_name\\\": \\\"default-domain.ECOM_Tenant_DND." + + "ECOM_Tenant_DND_mtn6_HngwOamNetVto.HNGWOAMNETVTO.OAM_landing-network-role_policy_05\\\", " + + "\\\"fq_name\\\": [ \\\"default-domain\\\", " + + "\\\"ECOM_Tenant_DND\\\", \\\"default-domain." + + "ECOM_Tenant_DND.ECOM_Tenant_DND_mtn6_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_landing-network-role_policy_05\\\" ], " + + "\\\"id_perms\\\": { \\\"user_visible\\\": true }, " + + "\\\"parent_type\\\": \\\"project\\\", \\\"network_policy_entries\\\": { " + + "\\\"policy_rule\\\": [ { " + + "\\\"action_list\\\": { \\\"apply_service\\\": [ " + + "\\\"testfqdn\\\" ], " + + "\\\"gateway_name\\\": null, \\\"qos_action\\\": null, " + + "\\\"log\\\": false , \\\"mirror_to\\\": null, " + + "\\\"simple_action\\\": null }, " + + "\\\"ethertype\\\": null, \\\"application\\\": [], " + + "\\\"direction\\\": \\\"<>\\\", \\\"dst_addresses\\\": [ " + + "{ \\\"network_policy\\\": null, " + + "\\\"security_group\\\": null, " + + "\\\"subnet\\\": null, \\\"virtual_network\\\": " + + "\\\"default-domain:ECOM_Tenant_DND:ECOM_Tenant_DND_int_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_net_10\\\" } ], " + + "\\\"dst_ports\\\": [ { " + + "\\\"end_port\\\": -1, \\\"start_port\\\": -1 " + + "} ], \\\"protocol\\\": \\\"any\\\", " + + "\\\"src_addresses\\\": [ { " + + "\\\"network_policy\\\": null, " + + "\\\"security_group\\\": null, " + + "\\\"subnet\\\": null, \\\"virtual_network\\\": " + + "\\\"default-domain:ECOM_Tenant_DND:ECOM_Tenant_DND_int_HngwOamNetVto." + + "HNGWOAMNETVTO.OAM_net_9\\\" } ], " + + "\\\"src_ports\\\": [ { " + + "\\\"end_port\\\": -1, " + + "\\\"start_port\\\": -1 } ] } " + + "] } }}}\"\n" + + "}"; + + String xmloutexpected = xmlin; + + String xmlout = XmlJsonUtil.removeEmptyStructJson(null, xmlin); + log.info(xmlout); + + Assert.assertEquals(xmloutexpected, xmlout); + } + @Test public void testRemoveEmptyStructXml() { String xmlin = "" + diff --git a/restapi-call-node/provider/src/test/resources/test-template.json b/restapi-call-node/provider/src/test/resources/test-template.json index 4adc6637..faefef31 100644 --- a/restapi-call-node/provider/src/test/resources/test-template.json +++ b/restapi-call-node/provider/src/test/resources/test-template.json @@ -51,6 +51,7 @@ "run-id": ${tmp.sdn-circuit-req-row[${1}].run-id}, "hostname": ${tmp.sdn-circuit-req-row[${1}].hostname}, "algo-request-reason": ${tmp.sdn-circuit-req-row[${1}].algo-request-reason} + "test-empty-value": ${tmp.sdn-circuit-req-row[${1}].test-empty-value} }, } ] -- 2.16.6