From: Dan Timoney Date: Tue, 19 Sep 2017 23:58:40 +0000 (+0000) Subject: Merge "Refinements to RestApiCall plugin" X-Git-Tag: v0.1.0~24 X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=4947ee3c0a6685eeb99d7fc9f0a159d135252f28;hp=02e1594ffee2231523d0486a5d8b590ff09581df;p=ccsdk%2Fsli%2Fplugins.git Merge "Refinements to RestApiCall plugin" --- diff --git a/fabric-discovery-plugin/provider/src/main/java/org/onap/ccsdk/sli/plugins/fabricdiscovery/FabricDiscoveryPlugin.java b/fabric-discovery-plugin/provider/src/main/java/org/onap/ccsdk/sli/plugins/fabricdiscovery/FabricDiscoveryPlugin.java index 7a0c68f4..66452758 100644 --- a/fabric-discovery-plugin/provider/src/main/java/org/onap/ccsdk/sli/plugins/fabricdiscovery/FabricDiscoveryPlugin.java +++ b/fabric-discovery-plugin/provider/src/main/java/org/onap/ccsdk/sli/plugins/fabricdiscovery/FabricDiscoveryPlugin.java @@ -39,6 +39,8 @@ public class FabricDiscoveryPlugin implements SvcLogicJavaPlugin, IFabricDiscove private ExecutorService service; private Map streamMap; private static final Logger LOG = LoggerFactory.getLogger(FabricDiscoveryPlugin.class); + private static final String STREAM_PREFIX = "ws://"; + private static final String FB_DISCOVERY_STATUS = "fb-response"; public FabricDiscoveryPlugin() { service = Executors.newFixedThreadPool(10); @@ -47,10 +49,29 @@ public class FabricDiscoveryPlugin implements SvcLogicJavaPlugin, IFabricDiscove @Override public void processDcNotificationStream (Map paramMap, SvcLogicContext ctx) throws SvcLogicException { - boolean enable = Boolean.parseBoolean(parseParam(paramMap, "enable", true, null)); + boolean enable; String stream = parseParam(paramMap, "stream", true, null); + String prefix = parseParam(paramMap, "contextPrefix", false, null); + String enableStr = parseParam(paramMap, "enable", true, null); + // Validate the input parameters + String pfx = (prefix != null) ? prefix + '.' : ""; + if ("true".equalsIgnoreCase(enableStr)) { + enable = true; + } else if ("false".equalsIgnoreCase(enableStr)) { + enable = false; + } else { + ctx.setAttribute(pfx + FB_DISCOVERY_STATUS, "Failure"); + throw new SvcLogicException("Incorrect parameter: enable. Valid values are ['true', 'false']"); + } + if (!STREAM_PREFIX.equalsIgnoreCase(stream.substring(0, 5))) { + ctx.setAttribute(pfx + FB_DISCOVERY_STATUS, "Failure"); + throw new SvcLogicException("Incorrect parameter: stream, Input is not a web socket address"); + } + + ctx.setAttribute(pfx + FB_DISCOVERY_STATUS, "Success"); LOG.info("{} monitoring notification stream: {}", (enable) ? "START" : "STOP", stream); + try { service.execute(new Runnable () { public void run () { 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..60697a42 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 @@ -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 | JSONException e) { boolean shouldRetry = false; - if (e.getCause() instanceof java.net.SocketException) { + if (e.getCause().getCause() instanceof SocketException) { shouldRetry = true; } @@ -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); } } @@ -270,7 +276,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { return value; } - protected String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format) { + protected String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format) + throws SvcLogicException { log.info("Building " + format + " started"); long t1 = System.currentTimeMillis(); @@ -291,7 +298,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); @@ -326,7 +333,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { 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 +345,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 +355,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++; @@ -365,8 +372,9 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { 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 +400,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 +458,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(); @@ -478,13 +492,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"); @@ -501,8 +509,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { 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,7 +533,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { r = sendHttpData(data, p); setResponseStatus(ctx, p.responsePrefix, r); - } catch (Exception e) { + } catch (SvcLogicException | IOException e) { log.error("Error sending the request: " + e.getMessage(), e); r = new HttpResponse(); @@ -563,7 +571,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 +588,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(); @@ -601,10 +616,17 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { 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(); @@ -648,7 +670,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin { if (r.body != null) ctx.setAttribute(pp + "httpResponse", r.body); - } catch (Exception e) { + } catch (SvcLogicException e) { log.error("Error sending the request: " + e.getMessage(), e); r = new HttpResponse(); @@ -682,7 +704,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("/")) @@ -706,7 +728,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(); 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..51c39478 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 p = new HashMap(); @@ -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,82 @@ 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 p = new HashMap(); + 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 p = new HashMap(); + 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 p = new HashMap(); + 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); + } }