Implementation for Restconf api call node
[ccsdk/sli/plugins.git] / restapi-call-node / provider / src / main / java / org / onap / ccsdk / sli / plugins / restapicall / RestapiCallNode.java
index c4ad4c5..6a9e81b 100644 (file)
 
 package org.onap.ccsdk.sli.plugins.restapicall;
 
+import com.sun.jersey.api.client.Client;
 import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
 import com.sun.jersey.api.client.UniformInterfaceException;
+import com.sun.jersey.api.client.WebResource;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
+import com.sun.jersey.api.client.filter.HTTPDigestAuthFilter;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import com.sun.jersey.oauth.client.OAuthClientFilter;
+import com.sun.jersey.oauth.signature.OAuthParameters;
+import com.sun.jersey.oauth.signature.OAuthSecrets;
+import org.apache.commons.lang3.StringUtils;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.ws.rs.core.EntityTag;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriBuilder;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.net.SocketException;
@@ -37,32 +62,11 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Properties;
 import java.util.Set;
 
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.ws.rs.core.EntityTag;
-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;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.WebResource;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.client.filter.HTTPBasicAuthFilter;
-import com.sun.jersey.client.urlconnection.HTTPSProperties;
+import static java.lang.Boolean.valueOf;
+import static org.onap.ccsdk.sli.plugins.restapicall.AuthType.fromString;
 
 public class RestapiCallNode implements SvcLogicJavaPlugin {
 
@@ -71,8 +75,12 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
     private String uebServers;
     private String defaultUebTemplateFileName = "/opt/bvc/restapi/templates/default-ueb-message.json";
     protected RetryPolicyStore retryPolicyStore;
+    protected static final String DME2_PROPERTIES_FILE_NAME = "dme2.properties";
+    protected static final String UEB_PROPERTIES_FILE_NAME = "ueb.properties";
+    protected static final String DEFAULT_PROPERTIES_DIR = "/opt/onap/ccsdk/data/properties";
+    protected static final String PROPERTIES_DIR_KEY = "SDNC_CONFIG_DIR";
 
-    protected RetryPolicyStore getRetryPolicyStore() {
+    public RetryPolicyStore getRetryPolicyStore() {
         return retryPolicyStore;
     }
 
@@ -81,12 +89,31 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
     }
 
     public RestapiCallNode() {
+        String configDir = System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR);
+
+        try (FileInputStream in = new FileInputStream(configDir + "/" + DME2_PROPERTIES_FILE_NAME)) {
+            Properties props = new Properties();
+            props.load(in);
+            this.retryPolicyStore = new RetryPolicyStore();
+            this.retryPolicyStore.setProxyServers(props.getProperty("proxyUrl"));
+            log.info("DME2 support enabled");
+        } catch (Exception e) {
+            log.warn("DME2 properties could not be read, DME2 support will not be enabled.", e);
+        }
 
+        try (FileInputStream in = new FileInputStream(configDir + "/" + UEB_PROPERTIES_FILE_NAME)) {
+            Properties props = new Properties();
+            props.load(in);
+            this.uebServers = props.getProperty("servers");
+            log.info("UEB support enabled");
+        } catch (Exception e) {
+            log.warn("UEB properties could not be read, UEB support will not be enabled.", e);
+        }
     }
 
      /**
      * Allows Directed Graphs  the ability to interact with REST APIs.
-     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * @param paramMap HashMap<String,String> of parameters passed by the DG to this function
      * <table border="1">
      *  <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th><th>example values</th></thead>
      *  <tbody>
@@ -94,6 +121,10 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
      *      <tr><td>restapiUrl</td><td>Mandatory</td><td>url to send the request to</td><td>https://sdncodl:8543/restconf/operations/L3VNF-API:create-update-vnf-request</td></tr>
      *      <tr><td>restapiUser</td><td>Optional</td><td>user name to use for http basic authentication</td><td>sdnc_ws</td></tr>
      *      <tr><td>restapiPassword</td><td>Optional</td><td>unencrypted password to use for http basic authentication</td><td>plain_password</td></tr>
+     *      <tr><td>oAuthConsumerKey</td><td>Optional</td><td>Consumer key to use for http oAuth authentication</td><td>plain_key</td></tr>
+     *      <tr><td>oAuthConsumerSecret</td><td>Optional</td><td>Consumer secret to use for http oAuth authentication</td><td>plain_secret</td></tr>
+     *      <tr><td>oAuthSignatureMethod</td><td>Optional</td><td>Consumer method to use for http oAuth authentication</td><td>method</td></tr>
+     *      <tr><td>oAuthVersion</td><td>Optional</td><td>Version http oAuth authentication</td><td>version</td></tr>
      *      <tr><td>contentType</td><td>Optional</td><td>http content type to set in the http header</td><td>usually application/json or application/xml</td></tr>
      *      <tr><td>format</td><td>Optional</td><td>should match request body format</td><td>json or xml</td></tr>
      *      <tr><td>httpMethod</td><td>Optional</td><td>http method to use when sending the request</td><td>get post put delete patch</td></tr>
@@ -104,6 +135,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
      *      <tr><td>customHttpHeaders</td><td>Optional</td><td>a list additional http headers to be passed in, follow the format in the example</td><td>X-CSI-MessageId=messageId,headerFieldName=headerFieldValue</td></tr>
      *      <tr><td>dumpHeaders</td><td>Optional</td><td>when true writes http header content to context memory</td><td>true or false</td></tr>
      *      <tr><td>partner</td><td>Optional</td><td>needed for DME2 calls</td><td>dme2proxy</td></tr>
+     *      <tr><td>returnRequestPayload</td><td>Optional</td><td>used to return payload built in the request</td><td>true or false</td></tr>
      *  </tbody>
      * </table>
      * @param ctx Reference to context memory
@@ -121,7 +153,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         RetryPolicy retryPolicy = null;
         HttpResponse r = new HttpResponse();
         try {
-            Parameters p = getParameters(paramMap);
+            Parameters p = getParameters(paramMap, new Parameters());
             if (p.partner != null) {
                 retryPolicy = retryPolicyStore.getRetryPolicy(p.partner);
             }
@@ -131,6 +163,8 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
             if (p.templateFileName != null) {
                 String reqTemplate = readFile(p.templateFileName);
                 req = buildXmlJsonRequest(ctx, reqTemplate, p.format);
+            } else if (p.requestBody != null) {
+                req = p.requestBody;
             }
             r = sendHttpRequest(req, p);
             setResponseStatus(ctx, p.responsePrefix, r);
@@ -140,6 +174,10 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
                     ctx.setAttribute(pp + "header." + a.getKey(), StringUtils.join(a.getValue(), ","));
                 }
             }
+            
+            if (p.returnRequestPayload && req != null) {
+               ctx.setAttribute(pp + "httpRequest", req);
+            }
 
             if (r.body != null && r.body.trim().length() > 0) {
                 ctx.setAttribute(pp + "httpResponse", r.body);
@@ -206,42 +244,88 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
             throw new SvcLogicException(String.valueOf(r.code) + ": " + r.message);
     }
 
-    protected Parameters getParameters(Map<String, String> paramMap) throws SvcLogicException {
-        Parameters p = new Parameters();
-        p.templateFileName = parseParam(paramMap, "templateFileName", false, null);
+    /**
+     * Returns parameters from the parameter map.
+     *
+     * @param paramMap parameter map
+     * @param p        parameters instance
+     * @return parameters filed instance
+     * @throws SvcLogicException when svc logic exception occurs
+     */
+    public static Parameters getParameters(Map<String, String> paramMap,
+                                           Parameters p)
+            throws SvcLogicException {
+        p.templateFileName = parseParam(paramMap, "templateFileName",
+                                        false, null);
+        p.requestBody = parseParam(paramMap, "requestBody", 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.restapiPassword = parseParam(paramMap, "restapiPassword", false,
+                                       null);
+        p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey",
+                                        false, null);
+        p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret",
+                                           false, null);
+        p.oAuthSignatureMethod = parseParam(paramMap, "oAuthSignatureMethod",
+                                            false, null);
+        p.oAuthVersion = parseParam(paramMap, "oAuthVersion", false, null);
         p.contentType = parseParam(paramMap, "contentType", false, null);
-        p.format = Format.fromString(parseParam(paramMap, "format", false, "json"));
-        p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod", false, "post"));
+        p.format = Format.fromString(parseParam(paramMap, "format", false,
+                                                "json"));
+        p.authtype = fromString(parseParam(paramMap, "authType", false,
+                                           "unspecified"));
+        p.httpMethod = HttpMethod.fromString(parseParam(paramMap, "httpMethod",
+                                                        false, "post"));
         p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null);
         p.listNameList = getListNameList(paramMap);
         String skipSendingStr = paramMap.get("skipSending");
         p.skipSending = "true".equalsIgnoreCase(skipSendingStr);
-        p.convertResponse = Boolean.valueOf(parseParam(paramMap, "convertResponse", false, "true"));
-        p.trustStoreFileName = parseParam(paramMap, "trustStoreFileName", false, null);
-        p.trustStorePassword = parseParam(paramMap, "trustStorePassword", false, null);
-        p.keyStoreFileName = parseParam(paramMap, "keyStoreFileName", false, null);
-        p.keyStorePassword = parseParam(paramMap, "keyStorePassword", false, null);
-        p.ssl = p.trustStoreFileName != null && p.trustStorePassword != null && p.keyStoreFileName != null &&
-                p.keyStorePassword != null;
-        p.customHttpHeaders = parseParam(paramMap, "customHttpHeaders", false, null);
+        p.convertResponse = valueOf(parseParam(paramMap, "convertResponse",
+                                               false, "true"));
+        p.trustStoreFileName = parseParam(paramMap, "trustStoreFileName",
+                                          false, null);
+        p.trustStorePassword = parseParam(paramMap, "trustStorePassword",
+                                          false, null);
+        p.keyStoreFileName = parseParam(paramMap, "keyStoreFileName",
+                                        false, null);
+        p.keyStorePassword = parseParam(paramMap, "keyStorePassword",
+                                        false, null);
+        p.ssl = p.trustStoreFileName != null && p.trustStorePassword != null
+                && p.keyStoreFileName != null && p.keyStorePassword != null;
+        p.customHttpHeaders = parseParam(paramMap, "customHttpHeaders",
+                                         false, null);
         p.partner = parseParam(paramMap, "partner", false, null);
-        p.dumpHeaders = Boolean.valueOf(parseParam(paramMap, "dumpHeaders", false, null));
+        p.dumpHeaders = valueOf(parseParam(paramMap, "dumpHeaders",
+                                           false, null));
+        p.returnRequestPayload = valueOf(parseParam(
+                paramMap, "returnRequestPayload", false, null));
         return p;
     }
 
-    private void validateUrl(String restapiUrl) throws SvcLogicException {
+    /**
+     * Validates the given URL in the parameters.
+     *
+     * @param restapiUrl rest api URL
+     * @throws SvcLogicException when URL validation fails
+     */
+    private static void validateUrl(String restapiUrl)
+            throws SvcLogicException {
         try {
             URI.create(restapiUrl);
         } catch (IllegalArgumentException e) {
-            throw new SvcLogicException("Invalid input of url " + e.getLocalizedMessage(), e);
+            throw new SvcLogicException("Invalid input of url "
+                                                + e.getLocalizedMessage(), e);
         }
     }
 
-    protected Set<String> getListNameList(Map<String, String> paramMap) {
+    /**
+     * Returns the list of list name.
+     *
+     * @param paramMap parameters map
+     * @return list of list name
+     */
+    private static Set<String> getListNameList(Map<String, String> paramMap) {
         Set<String> ll = new HashSet<>();
         for (Map.Entry<String,String> entry : paramMap.entrySet())
             if (entry.getKey().startsWith("listName"))
@@ -249,7 +333,19 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         return ll;
     }
 
-    protected String parseParam(Map<String, String> paramMap, String name, boolean required, String def)
+    /**
+     * Parses the parameter string map of property, validates if required,
+     * assigns default value if present and returns the value.
+     *
+     * @param paramMap string param map
+     * @param name     name of the property
+     * @param required if value required
+     * @param def      default value
+     * @return value of the property
+     * @throws SvcLogicException if required parameter value is empty
+     */
+    public static String parseParam(Map<String, String> paramMap, String name,
+                                    boolean required, String def)
             throws SvcLogicException {
         String s = paramMap.get(name);
 
@@ -382,8 +478,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
             try {
                 n = Integer.parseInt(value1);
             } catch (NumberFormatException e) {
-                throw new SvcLogicException("Invalid input of repeat interval, should be an integer value " +
-                    e.getLocalizedMessage(), e);
+                log.info("value1 not set or not a number, n will remain set at zero");
             }
 
             newTemplate.append(template.substring(k, i1));
@@ -418,7 +513,77 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         }
     }
 
-    protected HttpResponse sendHttpRequest(String request, Parameters p) throws SvcLogicException {
+    protected Client addAuthType(Client c, FileParam fp) throws SvcLogicException {
+        Parameters p = new Parameters();
+        p.restapiUser = fp.user;
+        p.restapiPassword = fp.password;
+        p.oAuthConsumerKey = fp.oAuthConsumerKey;
+        p.oAuthVersion = fp.oAuthVersion;
+        p.oAuthConsumerSecret = fp.oAuthConsumerSecret;
+        p.oAuthSignatureMethod = fp.oAuthSignatureMethod;
+        p.authtype = fp.authtype;
+        return addAuthType(c,p);
+    }
+
+    protected Client addAuthType(Client client, Parameters p) throws SvcLogicException {
+        if (p.authtype == AuthType.Unspecified){
+            if (p.restapiUser != null && p.restapiPassword != null)
+                client.addFilter(new HTTPBasicAuthFilter(p.restapiUser, p.restapiPassword));
+            else if(p.oAuthConsumerKey != null && p.oAuthConsumerSecret != null
+                    && p.oAuthSignatureMethod != null) {
+                OAuthParameters params = new OAuthParameters()
+                        .signatureMethod(p.oAuthSignatureMethod)
+                        .consumerKey(p.oAuthConsumerKey)
+                        .version(p.oAuthVersion);
+
+                OAuthSecrets secrets = new OAuthSecrets()
+                        .consumerSecret(p.oAuthConsumerSecret);
+                client.addFilter(new OAuthClientFilter(client.getProviders(), params, secrets));
+            }
+        } else {
+            if (p.authtype == AuthType.DIGEST) {
+                if (p.restapiUser != null && p.restapiPassword != null) {
+                    client.addFilter(new HTTPDigestAuthFilter(p.restapiUser, p.restapiPassword));
+                } else {
+                    throw new SvcLogicException("oAUTH authentication type selected but all restapiUser and restapiPassword " +
+                                                        "parameters doesn't exist", new Throwable());
+                }
+            } else if (p.authtype == AuthType.BASIC){
+                if (p.restapiUser != null && p.restapiPassword != null) {
+                    client.addFilter(new HTTPBasicAuthFilter(p.restapiUser, p.restapiPassword));
+                } else {
+                    throw new SvcLogicException("oAUTH authentication type selected but all restapiUser and restapiPassword " +
+                                                        "parameters doesn't exist", new Throwable());
+                }
+            } else if(p.authtype == AuthType.OAUTH ) {
+                if(p.oAuthConsumerKey != null && p.oAuthConsumerSecret != null && p.oAuthSignatureMethod != null) {
+                    OAuthParameters params = new OAuthParameters()
+                            .signatureMethod(p.oAuthSignatureMethod)
+                            .consumerKey(p.oAuthConsumerKey)
+                            .version(p.oAuthVersion);
+
+                    OAuthSecrets secrets = new OAuthSecrets()
+                            .consumerSecret(p.oAuthConsumerSecret);
+                    client.addFilter(new OAuthClientFilter(client.getProviders(), params, secrets));
+                } else {
+                    throw new SvcLogicException("oAUTH authentication type selected but all oAuthConsumerKey, oAuthConsumerSecret " +
+                                                        "and oAuthSignatureMethod parameters doesn't exist", new Throwable());
+                }
+            }
+        }
+        return client;
+    }
+
+    /**
+     * Receives the http response for the http request sent.
+     *
+     * @param request request msg
+     * @param p       parameters
+     * @return HTTP response
+     * @throws SvcLogicException when sending http request fails
+     */
+    public HttpResponse sendHttpRequest(String request, Parameters p)
+            throws SvcLogicException {
 
         ClientConfig config = new DefaultClientConfig();
         SSLContext ssl = null;
@@ -435,9 +600,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
 
         Client client = Client.create(config);
         client.setConnectTimeout(5000);
-        if (p.restapiUser != null)
-            client.addFilter(new HTTPBasicAuthFilter(p.restapiUser, p.restapiPassword));
-        WebResource webResource = client.resource(p.restapiUrl);
+        WebResource webResource = addAuthType(client,p).resource(p.restapiUrl);
 
         log.info("Sending request:");
         log.info(request);
@@ -455,6 +618,9 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
             }
 
             WebResource.Builder webResourceBuilder = webResource.accept(tt).type(tt1);
+            if(p.format == Format.NONE){
+                webResourceBuilder = webResource.header("","");
+            }
 
             if (p.customHttpHeaders != null && p.customHttpHeaders.length() > 0) {
                 String[] keyValuePairs = p.customHttpHeaders.split(",");
@@ -565,6 +731,11 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         public HttpMethod httpMethod;
         public String responsePrefix;
         public boolean skipSending;
+        public String oAuthConsumerKey;
+        public String oAuthConsumerSecret;
+        public String oAuthSignatureMethod;
+        public String oAuthVersion;
+        public AuthType authtype;
     }
 
     private FileParam getFileParameters(Map<String, String> paramMap) throws SvcLogicException {
@@ -577,6 +748,11 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         p.responsePrefix = parseParam(paramMap, "responsePrefix", false, null);
         String skipSendingStr = paramMap.get("skipSending");
         p.skipSending = "true".equalsIgnoreCase(skipSendingStr);
+        p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey", false, null);
+        p.oAuthVersion = parseParam(paramMap, "oAuthVersion", false, null);
+        p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret", false, null);
+        p.oAuthSignatureMethod = parseParam(paramMap, "oAuthSignatureMethod", false, null);
+        p.authtype = fromString(parseParam(paramMap, "authType", false, "unspecified"));
         return p;
     }
 
@@ -584,9 +760,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         Client client = Client.create();
         client.setConnectTimeout(5000);
         client.setFollowRedirects(true);
-        if (p.user != null)
-            client.addFilter(new HTTPBasicAuthFilter(p.user, p.password));
-        WebResource webResource = client.resource(p.url);
+        WebResource webResource = addAuthType(client,p).resource(p.url);
 
         log.info("Sending file");
         long t1 = System.currentTimeMillis();