diff options
Diffstat (limited to 'restapi-call-node/provider/src')
9 files changed, 446 insertions, 174 deletions
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 f2867f5a..4a1dfef5 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 @@ -21,6 +21,8 @@ package org.onap.ccsdk.sli.plugins.restapicall; +import static com.google.common.base.Preconditions.checkNotNull; + import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -29,57 +31,64 @@ import java.util.Map; import org.codehaus.jettison.json.JSONArray; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class JsonParser { +public final class JsonParser { private static final Logger log = LoggerFactory.getLogger(JsonParser.class); - @SuppressWarnings("unchecked") - public static Map<String, String> convertToProperties(String s) throws JSONException { - JSONObject json = new JSONObject(s); - - Map<String, Object> wm = new HashMap<>(); - Iterator<String> ii = json.keys(); - while (ii.hasNext()) { - String key1 = ii.next(); - wm.put(key1, json.get(key1)); - } - - Map<String, String> mm = new HashMap<>(); + private JsonParser() { + // Preventing instantiation of the same. + } - while (!wm.isEmpty()) - for (String key : new ArrayList<>(wm.keySet())) { - Object o = wm.get(key); - wm.remove(key); + @SuppressWarnings("unchecked") + public static Map<String, String> convertToProperties(String s) + throws SvcLogicException { + + checkNotNull(s, "Input should not be null."); + + try { + JSONObject json = new JSONObject(s); + Map<String, Object> wm = new HashMap<>(); + Iterator<String> ii = json.keys(); + while (ii.hasNext()) { + String key1 = ii.next(); + wm.put(key1, json.get(key1)); + } - if (o instanceof Boolean || o instanceof Number || o instanceof String) { - mm.put(key, o.toString()); + Map<String, String> mm = new HashMap<>(); - log.info("Added property: " + key + ": " + o.toString()); - } + while (!wm.isEmpty()) + for (String key : new ArrayList<>(wm.keySet())) { + Object o = wm.get(key); + wm.remove(key); - else if (o instanceof JSONObject) { - JSONObject jo = (JSONObject) o; - Iterator<String> i = jo.keys(); - while (i.hasNext()) { - String key1 = i.next(); - wm.put(key + "." + key1, jo.get(key1)); - } - } + if (o instanceof Boolean || o instanceof Number || o instanceof String) { + mm.put(key, o.toString()); - else if (o instanceof JSONArray) { - JSONArray ja = (JSONArray) o; - mm.put(key + "_length", String.valueOf(ja.length())); + log.info("Added property: {} : {}", key, o.toString()); + } else if (o instanceof JSONObject) { + JSONObject jo = (JSONObject) o; + Iterator<String> i = jo.keys(); + while (i.hasNext()) { + String key1 = i.next(); + wm.put(key + "." + key1, jo.get(key1)); + } + } else if (o instanceof JSONArray) { + JSONArray ja = (JSONArray) o; + mm.put(key + "_length", String.valueOf(ja.length())); - log.info("Added property: " + key + "_length" + ": " + String.valueOf(ja.length())); + log.info("Added property: {}_length: {}", key, String.valueOf(ja.length())); - for (int i = 0; i < ja.length(); i++) - wm.put(key + '[' + i + ']', ja.get(i)); + for (int i = 0; i < ja.length(); i++) + wm.put(key + '[' + i + ']', ja.get(i)); + } } - } - - return mm; + return mm; + } catch (JSONException e) { + throw new SvcLogicException("Unable to convert JSON to properties" + e.getLocalizedMessage(), e); + } } } diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java index ca227c72..c4ad4c55 100644 --- a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java +++ b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.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,7 +21,11 @@ package org.onap.ccsdk.sli.plugins.restapicall; +import com.sun.jersey.api.client.ClientHandlerException; +import com.sun.jersey.api.client.UniformInterfaceException; import java.io.FileInputStream; +import java.io.IOException; +import java.net.SocketException; import java.net.URI; import java.nio.file.Files; import java.nio.file.Paths; @@ -45,6 +49,7 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.UriBuilder; import org.apache.commons.lang3.StringUtils; +import org.codehaus.jettison.json.JSONException; import org.onap.ccsdk.sli.core.sli.SvcLogicContext; import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin; @@ -114,7 +119,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { throws SvcLogicException { RetryPolicy retryPolicy = null; - HttpResponse r = null; + HttpResponse r = new HttpResponse(); try { Parameters p = getParameters(paramMap); if (p.partner != null) { @@ -151,9 +156,9 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { ctx.setAttribute(pp + entry.getKey(), entry.getValue()); } } - } catch (Exception e) { + } catch (SvcLogicException e) { boolean shouldRetry = false; - if (e.getCause() instanceof java.net.SocketException) { + if (e.getCause().getCause() instanceof SocketException) { shouldRetry = true; } @@ -178,10 +183,10 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { URI retryUri = UriBuilder.fromUri(uri).host(uriTwo.getHost()).port(uriTwo.getPort()).scheme( uriTwo.getScheme()).build(); paramMap.put("restapiUrl", retryUri.toString()); - log.debug("URL was set to " + retryUri.toString()); - log.debug("Failed to communicate with host " + hostname + - ". Request will be re-attempted using the host " + retryString + "."); - log.debug("This is retry attempt " + retryCount + " out of " + retryPolicy.getMaximumRetries()); + log.debug("URL was set to {}", retryUri.toString()); + log.debug("Failed to communicate with host {}. Request will be re-attempted using the host {}.", + hostname, retryString); + log.debug("This is retry attempt {} out of {}", retryCount, retryPolicy.getMaximumRetries()); sendRequest(paramMap, ctx, retryCount); } else { log.debug("Maximum retries reached, calling setFailureResponseStatus."); @@ -190,7 +195,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } catch (Exception ex) { log.error("Could not attempt retry.", ex); String retryErrorMessage = - "Retry attempt has failed. No further retry shall be attempted, calling setFailureResponseStatus."; + "Retry attempt has failed. No further retry shall be attempted, calling " + + "setFailureResponseStatus."; setFailureResponseStatus(ctx, prefix, retryErrorMessage, r); } } @@ -204,6 +210,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { Parameters p = new Parameters(); p.templateFileName = parseParam(paramMap, "templateFileName", false, null); p.restapiUrl = parseParam(paramMap, "restapiUrl", true, null); + validateUrl(p.restapiUrl); p.restapiUser = parseParam(paramMap, "restapiUser", false, null); p.restapiPassword = parseParam(paramMap, "restapiPassword", false, null); p.contentType = parseParam(paramMap, "contentType", false, null); @@ -226,6 +233,14 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { return p; } + private void validateUrl(String restapiUrl) throws SvcLogicException { + try { + URI.create(restapiUrl); + } catch (IllegalArgumentException e) { + throw new SvcLogicException("Invalid input of url " + e.getLocalizedMessage(), e); + } + } + protected Set<String> getListNameList(Map<String, String> paramMap) { Set<String> ll = new HashSet<>(); for (Map.Entry<String,String> entry : paramMap.entrySet()) @@ -245,7 +260,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } s = s.trim(); - String value = ""; + StringBuilder value = new StringBuilder(); int i = 0; int i1 = s.indexOf('%'); while (i1 >= 0) { @@ -258,20 +273,21 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (varValue == null) varValue = "%" + varName + "%"; - value += s.substring(i, i1); - value += varValue; + value.append(s.substring(i, i1)); + value.append(varValue); i = i2 + 1; i1 = s.indexOf('%', i); } - value += s.substring(i); + value.append(s.substring(i)); - log.info("Parameter " + name + ": [" + value + "]"); - return value; + log.info("Parameter {}: [{}]", name, value); + return value.toString(); } - protected String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format) { - log.info("Building " + format + " started"); + protected String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format) + throws SvcLogicException { + log.info("Building {} started", format); long t1 = System.currentTimeMillis(); template = expandRepeats(ctx, template, 1); @@ -291,7 +307,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { int i2 = template.indexOf('}', i1 + 2); if (i2 < 0) - throw new RuntimeException("Template error: Matching } not found"); + throw new SvcLogicException("Template error: Matching } not found"); String var1 = template.substring(i1 + 2, i2); String value1 = format == Format.XML ? XmlJsonUtil.getXml(mm, var1) : XmlJsonUtil.getJson(mm, var1); @@ -321,12 +337,12 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { req = XmlJsonUtil.removeLastCommaJson(req); long t2 = System.currentTimeMillis(); - log.info("Building " + format + " completed. Time: " + (t2 - t1)); + log.info("Building {} completed. Time: {}", format, (t2 - t1)); return req; } - protected String expandRepeats(SvcLogicContext ctx, String template, int level) { + protected String expandRepeats(SvcLogicContext ctx, String template, int level) throws SvcLogicException { StringBuilder newTemplate = new StringBuilder(); int k = 0; while (k < template.length()) { @@ -338,7 +354,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { int i2 = template.indexOf(':', i1 + 9); if (i2 < 0) - throw new RuntimeException( + throw new SvcLogicException( "Template error: Context variable name followed by : is required after repeat"); // Find the closing }, store in i3 @@ -348,7 +364,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { while (nn > 0 && i < template.length()) { i3 = template.indexOf('}', i); if (i3 < 0) - throw new RuntimeException("Template error: Matching } not found"); + throw new SvcLogicException("Template error: Matching } not found"); int i32 = template.indexOf('{', i); if (i32 >= 0 && i32 < i3) { nn++; @@ -361,12 +377,13 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { String var1 = template.substring(i1 + 9, i2); String value1 = ctx.getAttribute(var1); - log.info(" " + var1 + ": " + value1); + log.info(" {}:{}", var1, value1); int n = 0; try { n = Integer.parseInt(value1); - } catch (Exception e) { - n = 0; + } catch (NumberFormatException e) { + throw new SvcLogicException("Invalid input of repeat interval, should be an integer value " + + e.getLocalizedMessage(), e); } newTemplate.append(template.substring(k, i1)); @@ -392,24 +409,23 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { return expandRepeats(ctx, newTemplate.toString(), level + 1); } - protected String readFile(String fileName) throws Exception { - byte[] encoded = Files.readAllBytes(Paths.get(fileName)); - return new String(encoded, "UTF-8"); + protected String readFile(String fileName) throws SvcLogicException { + try { + byte[] encoded = Files.readAllBytes(Paths.get(fileName)); + return new String(encoded, "UTF-8"); + } catch (IOException | SecurityException e) { + throw new SvcLogicException("Unable to read file " + fileName + e.getLocalizedMessage(), e); + } } - protected HttpResponse sendHttpRequest(String request, Parameters p) throws Exception { + protected HttpResponse sendHttpRequest(String request, Parameters p) throws SvcLogicException { + ClientConfig config = new DefaultClientConfig(); SSLContext ssl = null; if (p.ssl && p.restapiUrl.startsWith("https")) ssl = createSSLContext(p); if (ssl != null) { - HostnameVerifier hostnameVerifier = new HostnameVerifier() { - - @Override - public boolean verify(String hostname, SSLSession session) { - return true; - } - }; + HostnameVerifier hostnameVerifier = (hostname, session) -> true; config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hostnameVerifier, ssl)); @@ -451,7 +467,14 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { webResourceBuilder.header("X-ECOMP-RequestID",org.slf4j.MDC.get("X-ECOMP-RequestID")); - ClientResponse response = webResourceBuilder.method(p.httpMethod.toString(), ClientResponse.class, request); + ClientResponse response; + + try { + response = webResourceBuilder.method(p.httpMethod.toString(), ClientResponse.class, request); + } catch (UniformInterfaceException | ClientHandlerException e) { + throw new SvcLogicException("Exception while sending http request to client " + + e.getLocalizedMessage(), e); + } r.code = response.getStatus(); r.headers = response.getHeaders(); @@ -463,11 +486,11 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } long t2 = System.currentTimeMillis(); - log.info("Response received. Time: " + (t2 - t1)); - log.info("HTTP response code: " + r.code); - log.info("HTTP response message: " + r.message); + log.info("Response received. Time: {}", (t2 - t1)); + log.info("HTTP response code: {}", r.code); + log.info("HTTP response message: {}", r.message); logHeaders(r.headers); - log.info("HTTP response: " + r.body); + log.info("HTTP response: {}", r.body); return r; } @@ -478,13 +501,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { System.setProperty("javax.net.ssl.trustStore", p.trustStoreFileName); System.setProperty("javax.net.ssl.trustStorePassword", p.trustStorePassword); - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - - @Override - public boolean verify(String string, SSLSession ssls) { - return true; - } - }); + HttpsURLConnection.setDefaultHostnameVerifier((string, ssls) -> true); KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); KeyStore ks = KeyStore.getInstance("PKCS12"); @@ -496,13 +513,13 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { ctx.init(kmf.getKeyManagers(), null, null); return ctx; } catch (Exception e) { - log.error("Error creating SSLContext: " + e.getMessage(), e); + log.error("Error creating SSLContext: {}", e.getMessage(), e); } return null; } - protected void setFailureResponseStatus(SvcLogicContext ctx, String prefix, String errorMessage, HttpResponse r) { - HttpResponse resp = new HttpResponse(); + protected void setFailureResponseStatus(SvcLogicContext ctx, String prefix, String errorMessage, + HttpResponse resp) { resp.code = 500; resp.message = errorMessage; String pp = prefix != null ? prefix + '.' : ""; @@ -525,8 +542,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { r = sendHttpData(data, p); setResponseStatus(ctx, p.responsePrefix, r); - } catch (Exception e) { - log.error("Error sending the request: " + e.getMessage(), e); + } catch (SvcLogicException | IOException e) { + log.error("Error sending the request: {}", e.getMessage(), e); r = new HttpResponse(); r.code = 500; @@ -563,7 +580,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { return p; } - protected HttpResponse sendHttpData(byte[] data, FileParam p) { + protected HttpResponse sendHttpData(byte[] data, FileParam p) throws SvcLogicException { Client client = Client.create(); client.setConnectTimeout(5000); client.setFollowRedirects(true); @@ -580,11 +597,18 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (!p.skipSending) { String tt = "application/octet-stream"; - ClientResponse response = null; - if (p.httpMethod == HttpMethod.POST) - response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); - else if (p.httpMethod == HttpMethod.PUT) - response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + ClientResponse response; + try { + if (p.httpMethod == HttpMethod.POST) + response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); + else if (p.httpMethod == HttpMethod.PUT) + response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + else + throw new SvcLogicException("Http operation" + p.httpMethod + "not supported"); + } catch (UniformInterfaceException | ClientHandlerException e) { + throw new SvcLogicException("Exception while sending http request to client " + + e.getLocalizedMessage(), e); + } r.code = response.getStatus(); r.headers = response.getHeaders(); @@ -597,14 +621,21 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (r.code == 301) { String newUrl = response.getHeaders().getFirst("Location"); - log.info("Got response code 301. Sending same request to URL: " + newUrl); + log.info("Got response code 301. Sending same request to URL: {}", newUrl); webResource = client.resource(newUrl); - if (p.httpMethod == HttpMethod.POST) - response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); - else if (p.httpMethod == HttpMethod.PUT) - response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + try { + if (p.httpMethod == HttpMethod.POST) + response = webResource.accept(tt).type(tt).post(ClientResponse.class, data); + else if (p.httpMethod == HttpMethod.PUT) + response = webResource.accept(tt).type(tt).put(ClientResponse.class, data); + else + throw new SvcLogicException("Http operation" + p.httpMethod + "not supported"); + } catch (UniformInterfaceException | ClientHandlerException e) { + throw new SvcLogicException("Exception while sending http request to client " + + e.getLocalizedMessage(), e); + } r.code = response.getStatus(); etag = response.getEntityTag(); @@ -616,11 +647,11 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } long t2 = System.currentTimeMillis(); - log.info("Response received. Time: " + (t2 - t1)); - log.info("HTTP response code: " + r.code); - log.info("HTTP response message: " + r.message); + log.info("Response received. Time: {}", (t2 - t1)); + log.info("HTTP response code: {}", r.code); + log.info("HTTP response message: {}", r.message); logHeaders(r.headers); - log.info("HTTP response: " + r.body); + log.info("HTTP response: {}", r.body); return r; } @@ -635,7 +666,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { String req; if (p.templateFileName == null) { - log.info("No template file name specified. Using default UEB template: " + defaultUebTemplateFileName); + log.info("No template file name specified. Using default UEB template: {}", defaultUebTemplateFileName); p.templateFileName = defaultUebTemplateFileName; } @@ -648,8 +679,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (r.body != null) ctx.setAttribute(pp + "httpResponse", r.body); - } catch (Exception e) { - log.error("Error sending the request: " + e.getMessage(), e); + } catch (SvcLogicException e) { + log.error("Error sending the request: {}", e.getMessage(), e); r = new HttpResponse(); r.code = 500; @@ -682,7 +713,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { return p; } - protected HttpResponse postOnUeb(String request, UebParam p) throws Exception { + protected HttpResponse postOnUeb(String request, UebParam p) throws SvcLogicException { String[] urls = uebServers.split(" "); for (int i = 0; i < urls.length; i++) { if (!urls[i].endsWith("/")) @@ -694,7 +725,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { client.setConnectTimeout(5000); WebResource webResource = client.resource(urls[0]); - log.info("UEB URL: " + urls[0]); + log.info("UEB URL: {}", urls[0]); log.info("Sending request:"); log.info(request); long t1 = System.currentTimeMillis(); @@ -706,7 +737,14 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { String tt = "application/json"; String tt1 = tt + ";charset=UTF-8"; - ClientResponse response = webResource.accept(tt).type(tt1).post(ClientResponse.class, request); + ClientResponse response; + + try { + response = webResource.accept(tt).type(tt1).post(ClientResponse.class, request); + } catch (UniformInterfaceException | ClientHandlerException e) { + throw new SvcLogicException("Exception while posting http request to client " + + e.getLocalizedMessage(), e); + } r.code = response.getStatus(); r.headers = response.getHeaders(); @@ -715,10 +753,10 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { } long t2 = System.currentTimeMillis(); - log.info("Response received. Time: " + (t2 - t1)); - log.info("HTTP response code: " + r.code); + log.info("Response received. Time: {}", (t2 - t1)); + log.info("HTTP response code: {}", r.code); logHeaders(r.headers); - log.info("HTTP response:\n" + r.body); + log.info("HTTP response:\n {}", r.body); return r; } @@ -731,7 +769,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { log.info("Properties:"); for (String name : ll) - log.info("--- " + name + ": " + String.valueOf(mm.get(name))); + log.info("--- {}:{}", name, String.valueOf(mm.get(name))); } protected void logHeaders(MultivaluedMap<String, String> mm) { @@ -746,7 +784,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { Collections.sort(ll); for (String name : ll) - log.info("--- " + name + ": " + String.valueOf(mm.get(name))); + log.info("--- {}:{}", name, String.valueOf(mm.get(name))); } public void setUebServers(String uebServers) { 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 e80ca508..965d3daa 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 @@ -29,10 +29,14 @@ import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class XmlJsonUtil { +public final class XmlJsonUtil { private static final Logger log = LoggerFactory.getLogger(XmlJsonUtil.class); + private XmlJsonUtil() { + // Preventing instantiation of the same. + } + public static String getXml(Map<String, String> varmap, String var) { boolean escape = true; if (var.startsWith("'")) { @@ -99,7 +103,7 @@ public class XmlJsonUtil { try { length = Integer.parseInt(lengthStr); } catch (Exception e) { - log.warn("Invalid number for " + var + "_length:" + lengthStr); + log.warn("Invalid number for {}_length:{}", var, lengthStr, e); } } @@ -128,23 +132,24 @@ public class XmlJsonUtil { if (o instanceof Map) { StringBuilder ss = new StringBuilder(); Map<String, Object> mm = (Map<String, Object>) o; - for (String k : mm.keySet()) { - Object v = mm.get(k); + for (Map.Entry<String, Object> entry: mm.entrySet()) { + Object v = entry.getValue(); + String key = entry.getKey(); if (v instanceof String) { String s = escape ? escapeXml((String) v) : (String) v; - ss.append(pad(indent)).append('<').append(k).append('>'); + ss.append(pad(indent)).append('<').append(key).append('>'); ss.append(s); - ss.append("</").append(k).append('>').append('\n'); + ss.append("</").append(key).append('>').append('\n'); } else if (v instanceof Map) { - ss.append(pad(indent)).append('<').append(k).append('>').append('\n'); + ss.append(pad(indent)).append('<').append(key).append('>').append('\n'); ss.append(generateXml(v, indent + 1, escape)); - ss.append(pad(indent)).append("</").append(k).append('>').append('\n'); + ss.append(pad(indent)).append("</").append(key).append('>').append('\n'); } else if (v instanceof List) { List<Object> ll = (List<Object>) v; for (Object o1 : ll) { - ss.append(pad(indent)).append('<').append(k).append('>').append('\n'); + ss.append(pad(indent)).append('<').append(key).append('>').append('\n'); ss.append(generateXml(o1, indent + 1, escape)); - ss.append(pad(indent)).append("</").append(k).append('>').append('\n'); + ss.append(pad(indent)).append("</").append(key).append('>').append('\n'); } } } @@ -181,13 +186,13 @@ public class XmlJsonUtil { ss.append("{\n"); boolean first = true; - for (String k : mm.keySet()) { + for (Map.Entry<String, Object> entry : mm.entrySet()) { if (!first) ss.append(",\n"); first = false; - - Object v = mm.get(k); - ss.append(pad(indent + 1)).append('"').append(k).append("\": "); + Object v = entry.getValue(); + String key = entry.getKey(); + ss.append(pad(indent + 1)).append('"').append(key).append("\": "); generateJson(ss, v, indent + 1, false, escape); } @@ -364,9 +369,9 @@ public class XmlJsonUtil { } private static String pad(int n) { - String s = ""; + StringBuilder s = new StringBuilder(); for (int i = 0; i < n; i++) - s += Character.toString('\t'); - return s; + 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 61b0e31d..9aede5b7 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 @@ -21,37 +21,49 @@ package org.onap.ccsdk.sli.plugins.restapicall; +import static com.google.common.base.Preconditions.checkNotNull; + import java.io.ByteArrayInputStream; +import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; -public class XmlParser { +public final class XmlParser { private static final Logger log = LoggerFactory.getLogger(XmlParser.class); - public static Map<String, String> convertToProperties(String s, Set<String> listNameList) { + private XmlParser() { + // Preventing instantiation of the same. + } + + public static Map<String, String> convertToProperties(String s, Set<String> listNameList) + throws SvcLogicException { + + checkNotNull(s, "Input should not be null."); + Handler handler = new Handler(listNameList); try { SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); InputStream in = new ByteArrayInputStream(s.getBytes()); saxParser.parse(in, handler); - } catch (Exception e) { - e.printStackTrace(); + } catch (ParserConfigurationException | IOException | SAXException | NumberFormatException e) { + throw new SvcLogicException("Unable to convert XML to properties" + e.getLocalizedMessage(), e); } - return handler.getProperties(); } @@ -72,8 +84,8 @@ public class XmlParser { this.listNameList = new HashSet<>(); } - String currentName = ""; - String currentValue = ""; + StringBuilder currentName = new StringBuilder(); + StringBuilder currentValue = new StringBuilder(); @Override public void startElement(String uri, String localName, String qName, Attributes attributes) @@ -88,15 +100,16 @@ public class XmlParser { name = name.substring(i2 + 1); if (currentName.length() > 0) - currentName += Character.toString('.'); - currentName += name; + currentName.append(Character.toString('.')); + currentName.append(name); - String listName = removeIndexes(currentName); + String listName = removeIndexes(currentName.toString()); if (listNameList.contains(listName)) { - int len = getInt(properties, currentName + "_length"); - properties.put(currentName + "_length", String.valueOf(len + 1)); - currentName += "[" + len + "]"; + String n = currentName.toString() + "_length"; + int len = getInt(properties, n); + properties.put(n, String.valueOf(len + 1)); + currentName.append("[").append(len).append("]"); } } @@ -111,20 +124,19 @@ public class XmlParser { if (i2 >= 0) name = name.substring(i2 + 1); - if (currentValue.trim().length() > 0) { - currentValue = currentValue.trim(); - properties.put(currentName, currentValue); - - log.info("Added property: " + currentName + ": " + currentValue); + String s = currentValue.toString().trim(); + if (s.length() > 0) { + properties.put(currentName.toString(), s); - currentValue = ""; + log.info("Added property: {} : {}", currentName, s); + currentValue = new StringBuilder(); } int i1 = currentName.lastIndexOf("." + name); if (i1 <= 0) - currentName = ""; + currentName = new StringBuilder(); else - currentName = currentName.substring(0, i1); + currentName = new StringBuilder(currentName.substring(0, i1)); } @Override @@ -132,7 +144,7 @@ public class XmlParser { super.characters(ch, start, length); String value = new String(ch, start, length); - currentValue += value; + currentValue.append(value); } private static int getInt(Map<String, String> mm, String name) { @@ -143,7 +155,7 @@ public class XmlParser { } private String removeIndexes(String currentName) { - String s = ""; + StringBuilder b = new StringBuilder(); boolean add = true; for (int i = 0; i < currentName.length(); i++) { char c = currentName.charAt(i); @@ -152,9 +164,9 @@ public class XmlParser { else if (c == ']') add = true; else if (add) - s += Character.toString(c); + b.append(Character.toString(c)); } - return s; + return b.toString(); } } } diff --git a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestJsonParser.java b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestJsonParser.java index dbca5ad7..5526be81 100644 --- a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestJsonParser.java +++ b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestJsonParser.java @@ -22,6 +22,7 @@ package jtest.org.onap.ccsdk.sli.plugins.restapicall; import java.io.BufferedReader; +import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Collections; @@ -29,6 +30,7 @@ import java.util.List; import java.util.Map; import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.plugins.restapicall.JsonParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -38,30 +40,34 @@ public class TestJsonParser { private static final Logger log = LoggerFactory.getLogger(TestJsonParser.class); @Test - public void test() throws Exception { + public void test() throws SvcLogicException, IOException { BufferedReader in = new BufferedReader( new InputStreamReader(ClassLoader.getSystemResourceAsStream("test.json")) ); - String ss = ""; - String line = null; + StringBuilder b = new StringBuilder(); + String line; while ((line = in.readLine()) != null) - ss += line + '\n'; + b.append(line).append('\n'); - Map<String, String> mm = JsonParser.convertToProperties(ss); + Map<String, String> mm = JsonParser.convertToProperties(b.toString()); logProperties(mm); in.close(); } + @Test(expected = NullPointerException.class) + public void testNullString() throws SvcLogicException { + JsonParser.convertToProperties(null); + } + private void logProperties(Map<String, String> mm) { List<String> ll = new ArrayList<>(); for (Object o : mm.keySet()) ll.add((String) o); Collections.sort(ll); - log.info("Properties:"); for (String name : ll) - log.info("--- " + name + ": " + mm.get(name)); + log.info("--- {}: {}", name, mm.get(name)); } } diff --git a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java index ff971480..118d97d3 100644 --- a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java +++ b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java @@ -26,6 +26,7 @@ import java.util.Map; import org.junit.Test; import org.onap.ccsdk.sli.core.sli.SvcLogicContext; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,7 +37,7 @@ public class TestRestapiCallNode { @Test - public void testDelete() throws Exception { + public void testDelete() throws SvcLogicException { SvcLogicContext ctx = new SvcLogicContext(); Map<String, String> p = new HashMap<String, String>(); @@ -51,7 +52,7 @@ public class TestRestapiCallNode { } @Test - public void testJsonTemplate() throws Exception { + public void testJsonTemplate() throws SvcLogicException { SvcLogicContext ctx = new SvcLogicContext(); ctx.setAttribute("tmp.sdn-circuit-req-row_length", "3"); ctx.setAttribute("tmp.sdn-circuit-req-row[0].source-uid", "APIDOC-123"); @@ -89,4 +90,109 @@ public class TestRestapiCallNode { RestapiCallNode rcn = new RestapiCallNode(); rcn.sendRequest(p, ctx); } + + @Test(expected = SvcLogicException.class) + public void testInvalidRepeatTimes() throws SvcLogicException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("tmp.sdn-circuit-req-row_length", "a"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].source-uid", "APIDOC-123"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].action", "delete"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-timestamp", "2016-09-09 16:30:35.0"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].processing-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].service-clfi", "testClfi1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].clci", "clci"); + + Map<String, String> p = new HashMap<String, String>(); + p.put("templateFileName", "src/test/resources/test-template.json"); + p.put("restapiUrl", "http://echo.getpostman.com"); + p.put("restapiUser", "user1"); + p.put("restapiPassword", "abc123"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("responsePrefix", "response"); + p.put("skipSending", "true"); + + RestapiCallNode rcn = new RestapiCallNode(); + rcn.sendRequest(p, ctx); + } + + @Test(expected = SvcLogicException.class) + public void testInvalidTemplatePath() throws SvcLogicException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("tmp.sdn-circuit-req-row_length", "1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].source-uid", "APIDOC-123"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].action", "delete"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-timestamp", "2016-09-09 16:30:35.0"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].processing-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].service-clfi", "testClfi1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].clci", "clci"); + + Map<String, String> p = new HashMap<String, String>(); + p.put("templateFileName", "src/test/resourcess/test-template.json"); + p.put("restapiUrl", "http://echo.getpostman.com"); + p.put("restapiUser", "user1"); + p.put("restapiPassword", "abc123"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("responsePrefix", "response"); + p.put("skipSending", "true"); + + RestapiCallNode rcn = new RestapiCallNode(); + rcn.sendRequest(p, ctx); + } + + @Test(expected = SvcLogicException.class) + public void testWithoutSkipSending() throws SvcLogicException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("tmp.sdn-circuit-req-row_length", "1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].source-uid", "APIDOC-123"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].action", "delete"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-timestamp", "2016-09-09 16:30:35.0"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].processing-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].service-clfi", "testClfi1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].clci", "clci"); + + Map<String, String> p = new HashMap<String, String>(); + p.put("templateFileName", "src/test/resources/test-template.json"); + p.put("restapiUrl", "http://echo.getpostman.com"); + p.put("restapiUser", "user1"); + p.put("restapiPassword", "abc123"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("responsePrefix", "response"); + p.put("skipSending", "false"); + + RestapiCallNode rcn = new RestapiCallNode(); + rcn.sendRequest(p, ctx); + } + + + @Test(expected = SvcLogicException.class) + public void testWithInvalidURI() throws SvcLogicException { + SvcLogicContext ctx = new SvcLogicContext(); + ctx.setAttribute("tmp.sdn-circuit-req-row_length", "1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].source-uid", "APIDOC-123"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].action", "delete"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-timestamp", "2016-09-09 16:30:35.0"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].request-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].processing-status", "New"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].service-clfi", "testClfi1"); + ctx.setAttribute("tmp.sdn-circuit-req-row[0].clci", "clci"); + + Map<String, String> p = new HashMap<String, String>(); + p.put("templateFileName", "src/test/resources/test-template.json"); + p.put("restapiUrl", "http://echo. getpostman.com"); + p.put("restapiUser", "user1"); + p.put("restapiPassword", "abc123"); + p.put("format", "json"); + p.put("httpMethod", "post"); + p.put("responsePrefix", "response"); + p.put("skipSending", "false"); + + RestapiCallNode rcn = new RestapiCallNode(); + rcn.sendRequest(p, ctx); + } } diff --git a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestXmlParser.java b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestXmlParser.java index 544d259e..c6bf4a8b 100644 --- a/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestXmlParser.java +++ b/restapi-call-node/provider/src/test/java/jtest/org/onap/ccsdk/sli/plugins/restapicall/TestXmlParser.java @@ -21,6 +21,9 @@ package jtest.org.onap.ccsdk.sli.plugins.restapicall; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.core.Is.is; + import java.io.BufferedReader; import java.io.InputStreamReader; import java.util.ArrayList; @@ -31,6 +34,7 @@ import java.util.Map; import java.util.Set; import org.junit.Test; +import org.onap.ccsdk.sli.core.sli.SvcLogicException; import org.onap.ccsdk.sli.plugins.restapicall.XmlParser; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,10 +48,10 @@ public class TestXmlParser { BufferedReader in = new BufferedReader( new InputStreamReader(ClassLoader.getSystemResourceAsStream("test3.xml")) ); - String ss = ""; - String line = null; + StringBuilder b = new StringBuilder(); + String line; while ((line = in.readLine()) != null) - ss += line + '\n'; + b.append(line).append('\n'); Set<String> listNameList = new HashSet<String>(); listNameList.add("project.dependencies.dependency"); @@ -57,10 +61,50 @@ public class TestXmlParser { listNameList.add("project.build.pluginManagement." + "plugins.plugin.configuration.lifecycleMappingMetadata.pluginExecutions.pluginExecution"); - Map<String, String> mm = XmlParser.convertToProperties(ss, listNameList); + Map<String, String> mm = XmlParser.convertToProperties(b.toString(), listNameList); + logProperties(mm); + in.close(); + } + + @Test + public void testValidLength() throws Exception { + BufferedReader in = new BufferedReader( + new InputStreamReader(ClassLoader.getSystemResourceAsStream("test3.xml")) + ); + StringBuilder b = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) + b.append(line).append('\n'); + + Set<String> listNameList = new HashSet<String>(); + listNameList.add("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfImport"); + listNameList.add("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfExport"); + + Map<String, String> mm = XmlParser.convertToProperties(b.toString(), listNameList); + + assertThat(mm.get("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfExport[5]"), is("SET_RESET_LP")); + assertThat(mm.get("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfImport[0]"), is("SET_BVOIP_IN")); logProperties(mm); + in.close(); + } + @Test(expected = SvcLogicException.class) + public void testInvalidLength() throws Exception { + BufferedReader in = new BufferedReader( + new InputStreamReader(ClassLoader.getSystemResourceAsStream("invalidlength.xml")) + ); + StringBuilder b = new StringBuilder(); + String line; + while ((line = in.readLine()) != null) + b.append(line).append('\n'); + + Set<String> listNameList = new HashSet<String>(); + listNameList.add("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfImport"); + listNameList.add("ApplyGroupResponse.ApplyGroupResponseData.VrfDetails.VrfExport"); + + Map<String, String> mm = XmlParser.convertToProperties(b.toString(), listNameList); + logProperties(mm); in.close(); } diff --git a/restapi-call-node/provider/src/test/resources/invalidlength.xml b/restapi-call-node/provider/src/test/resources/invalidlength.xml new file mode 100644 index 00000000..c086d564 --- /dev/null +++ b/restapi-call-node/provider/src/test/resources/invalidlength.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> +<!-- + ============LICENSE_START======================================================= + openECOMP : SDN-C + ================================================================================ + Copyright (C) 2017 AT&T Intellectual Property. All rights + reserved. + ================================================================================ + 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. + ============LICENSE_END========================================================= + --> + +<ApplyGroupResponse xmlns="http://onap.org/vpn/schema/v1" + xmlns:ns2="http://onap.org/prov/vpn/schema/v2"> + <ApplyGroupResponseData> + <ServiceInstanceId>ICOREPVC-81114561</ServiceInstanceId> + <VrfDetails> + <End2EndVpnKey>VPNL811182</End2EndVpnKey> + <VpnId>811182</VpnId> + <VrfName>21302:811182</VrfName> + <VrfImport>SET_BVOIP_IN</VrfImport> + <VrfImport>SET6_BVOIP_IN</VrfImport> + <VrfExport_length>a</VrfExport_length> + <VrfExport>SET6_DSU</VrfExport> + <VrfExport>SET_DSU</VrfExport> + <VrfExport>SET6_MANAGED</VrfExport> + <VrfExport>SET_MANAGED</VrfExport> + <VrfExport>SET_LOVRF_COMMUNITY</VrfExport> + <VrfExport>SET_RESET_LP</VrfExport> + <ApplyGroup> + <ns2:ApplyGroup>AG_MAX_MCASTROUTES</ns2:ApplyGroup> + </ApplyGroup> + </VrfDetails> + </ApplyGroupResponseData> + <response-code>200</response-code> + <response-message>Success</response-message> + <ack-final-indicator>Y</ack-final-indicator> +</ApplyGroupResponse> + diff --git a/restapi-call-node/provider/src/test/resources/test.json b/restapi-call-node/provider/src/test/resources/test.json index a34f7e2a..b48eb6b4 100644 --- a/restapi-call-node/provider/src/test/resources/test.json +++ b/restapi-call-node/provider/src/test/resources/test.json @@ -27,7 +27,10 @@ "number-primary-servers": "2", "equipment-id": "Server1", "server-model": "Unknown", - "server-id": "Server1" + "server-id": "Server1", + "test-node" : { + "test-inner-node" : "Test-Value" + } } ], "resource-state": { |