implement generic retry and partners in restapicallnode 32/88032/9
authorSmokowski, Kevin (ks6305) <kevin.smokowski@att.com>
Fri, 17 May 2019 21:09:28 +0000 (21:09 +0000)
committerKevin Smokowski <kevin.smokowski@att.com>
Wed, 29 May 2019 15:43:52 +0000 (15:43 +0000)
implement generic retry and partners in restapicallnode

Change-Id: I436622dda5a5a83b029c935b929f43e05d37a2a0
Issue-ID: CCSDK-1343
Signed-off-by: Smokowski, Kevin (ks6305) <kevin.smokowski@att.com>
restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/Parameters.java [changed mode: 0644->0755]
restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/PartnerDetails.java [new file with mode: 0755]
restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RestapiCallNode.java [changed mode: 0644->0755]
restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicy.java
restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicyStore.java [deleted file]
restapi-call-node/provider/src/test/java/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java [changed mode: 0644->0755]
restapi-call-node/provider/src/test/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java [new file with mode: 0755]
restapi-call-node/provider/src/test/resources/partners.json [new file with mode: 0755]
restconf-client/provider/src/main/java/org/onap/ccsdk/sli/plugins/restconfapicall/RestconfApiCallNode.java

old mode 100644 (file)
new mode 100755 (executable)
index aeb07c4..8b9cdc3
@@ -26,6 +26,7 @@ import java.util.Set;
 public class Parameters {
     public String templateFileName;
     public String restapiUrl;
+    public String restapiUrlSuffix;
     public String restapiUser;
     public String restapiPassword;
     public Format format;
diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/PartnerDetails.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/PartnerDetails.java
new file mode 100755 (executable)
index 0000000..1cd4b99
--- /dev/null
@@ -0,0 +1,14 @@
+package org.onap.ccsdk.sli.plugins.restapicall;\r
+\r
+public class PartnerDetails {\r
+    protected String username;\r
+    protected String password;\r
+    protected String url;\r
+\r
+    public PartnerDetails(String username, String password, String url) {\r
+       this.username = username;\r
+       this.password = password;\r
+       this.url = url;\r
+    }\r
+\r
+}\r
old mode 100644 (file)
new mode 100755 (executable)
index 9b50eaa..34e5dec
@@ -37,6 +37,7 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -57,7 +58,10 @@ import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.MultivaluedMap;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.UriBuilder;
+import javax.ws.rs.core.Response;
 import org.apache.commons.lang3.StringUtils;
+import org.codehaus.jettison.json.JSONException;
+import org.codehaus.jettison.json.JSONObject;
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
@@ -66,6 +70,8 @@ import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport;
 import org.glassfish.jersey.media.multipart.MultiPart;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
 import org.glassfish.jersey.media.multipart.file.FileDataBodyPart;
+import org.glassfish.jersey.client.oauth1.ConsumerCredentials;
+import org.glassfish.jersey.client.oauth1.OAuth1ClientSupport;
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
 import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
@@ -74,34 +80,36 @@ import org.slf4j.LoggerFactory;
 
 public class RestapiCallNode implements SvcLogicJavaPlugin {
 
-    protected static final String DME2_PROPERTIES_FILE_NAME = "dme2.properties";
+    protected static final String PARTNERS_FILE_NAME = "partners.json";
     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";
 
     private static final Logger log = LoggerFactory.getLogger(RestapiCallNode.class);
-    protected RetryPolicyStore retryPolicyStore;
     private String uebServers;
     private String defaultUebTemplateFileName = "/opt/bvc/restapi/templates/default-ueb-message.json";
 
     private String responseReceivedMessage = "Response received. Time: {}";
     private String responseHttpCodeMessage = "HTTP response code: {}";
     private String requestPostingException = "Exception while posting http request to client ";
-    private static String skipSendingMessage = "skipSending";
-    private static String responsePrefix = "responsePrefix";
-    private static String restapiUrlString = "restapiUrl";
+    protected static final String skipSendingMessage = "skipSending";
+    protected static final String responsePrefix = "responsePrefix";
+    protected static final String restapiUrlString = "restapiUrl";
+    protected static final String restapiUserKey = "restapiUser";
+    protected static final String restapiPasswordKey = "restapiPassword";
 
-    public RestapiCallNode() {
-        String configDir = System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR);
+    protected HashMap<String,PartnerDetails> partnerStore;
 
-        try (FileInputStream in = new FileInputStream(configDir + "/" + DME2_PROPERTIES_FILE_NAME)) {
-            Properties props = new Properties();
-            props.load(in);
-            retryPolicyStore = new RetryPolicyStore();
-            retryPolicyStore.setProxyServers(props.getProperty("proxyUrl"));
-            log.info("DME2 support enabled");
+    public RestapiCallNode() {
+       String configDir = System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR);
+        try {
+            String jsonString = readFile(configDir + "/" + PARTNERS_FILE_NAME);
+            JSONObject partners = new JSONObject(jsonString);
+            partnerStore = new HashMap<String,PartnerDetails>();
+            loadPartners(partners);
+            log.info("Partners support enabled");
         } catch (Exception e) {
-            log.warn("DME2 properties could not be read, DME2 support will not be enabled.", e);
+            log.warn("Partners file could not be read, Partner support will not be enabled.", e);
         }
 
         try (FileInputStream in = new FileInputStream(configDir + "/" + UEB_PROPERTIES_FILE_NAME)) {
@@ -114,6 +122,35 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         }
     }
 
+    protected void loadPartners(JSONObject partners) {
+       Iterator<String> keys = partners.keys();
+       String partnerUserKey = "user";
+       String partnerPasswordKey = "password";
+       String partnerUrlKey = "url";
+
+       while (keys.hasNext()) {
+           String partnerKey = keys.next();
+           try {
+               JSONObject partnerObject = (JSONObject) partners.get(partnerKey);
+               if (partnerObject.has(partnerUserKey) && partnerObject.has(partnerPasswordKey)) {
+                   String url = null;
+                   if (partnerObject.has(partnerUrlKey)) {
+                       url = partnerObject.getString(partnerUrlKey);
+                   }
+                   String userName = partnerObject.getString(partnerUserKey);
+                   String password = partnerObject.getString(partnerPasswordKey);
+                   PartnerDetails details = new PartnerDetails(userName, password, url);
+                   partnerStore.put(partnerKey, details);
+                   log.info("mapped partner using partner key " + partnerKey);
+               } else {
+                   log.info("Partner " + partnerKey + " is missing required keys, it won't be mapped");
+               }
+           } catch (JSONException e) {
+               log.info("Couldn't map the partner using partner key " + partnerKey, e);
+           }
+       }
+    }
+
     /**
      * Returns parameters from the parameter map.
      *
@@ -125,14 +162,21 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
     public static Parameters getParameters(Map<String, String> paramMap,
         Parameters p)
         throws SvcLogicException {
-        p.templateFileName = parseParam(paramMap, "templateFileName",
+
+       p.templateFileName = parseParam(paramMap, "templateFileName",
             false, null);
         p.requestBody = parseParam(paramMap, "requestBody", false, null);
         p.restapiUrl = parseParam(paramMap, restapiUrlString, true, null);
         validateUrl(p.restapiUrl);
-        p.restapiUser = parseParam(paramMap, "restapiUser", false, null);
-        p.restapiPassword = parseParam(paramMap, "restapiPassword", false,
+        p.restapiUrlSuffix = parseParam(paramMap, "restapiUrlSuffix",
+                false, null);
+        p.restapiUser = parseParam(paramMap, restapiUserKey, false, null);
+        p.restapiPassword = parseParam(paramMap, restapiPasswordKey, false,
             null);
+        if(p.restapiUrlSuffix != null) {
+            p.restapiUrl = p.restapiUrl + p.restapiUrlSuffix;
+            validateUrl(p.restapiUrl);
+        }
         p.oAuthConsumerKey = parseParam(paramMap, "oAuthConsumerKey",
             false, null);
         p.oAuthConsumerSecret = parseParam(paramMap, "oAuthConsumerSecret",
@@ -185,14 +229,19 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
      * @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);
-        }
+    private static void validateUrl(String restapiUrl) throws SvcLogicException {
+       if (restapiUrl.contains(",")) {
+           String[] urls = restapiUrl.split(",");
+           for(String url : urls) {
+               validateUrl(url);
+           }
+       } else {
+           try {
+               URI.create(restapiUrl);
+           } catch (IllegalArgumentException e) {
+               throw new SvcLogicException("Invalid input of url " + e.getLocalizedMessage(), e);
+           }
+       }
     }
 
     /**
@@ -262,14 +311,6 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         return value.toString();
     }
 
-    public RetryPolicyStore getRetryPolicyStore() {
-        return retryPolicyStore;
-    }
-
-    public void setRetryPolicyStore(RetryPolicyStore retryPolicyStore) {
-        this.retryPolicyStore = retryPolicyStore;
-    }
-
     /**
      * Allows Directed Graphs  the ability to interact with REST APIs.
      * @param paramMap HashMap<String,String> of parameters passed by the DG to this function
@@ -293,7 +334,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
      *      <tr><td>convertResponse </td><td>Optional</td><td>whether the response should be converted</td><td>true or false</td></tr>
      *      <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>partner</td><td>Optional</td><td>used to retrieve username, password and url if partner store exists</td><td>aaf</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>
@@ -306,15 +347,17 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         sendRequest(paramMap, ctx, null);
     }
 
-    public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx, Integer retryCount)
+    protected void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx, RetryPolicy retryPolicy)
         throws SvcLogicException {
 
-        RetryPolicy retryPolicy = null;
         HttpResponse r = new HttpResponse();
         try {
+            handlePartner(paramMap);           
             Parameters p = getParameters(paramMap, new Parameters());
-            if (p.partner != null) {
-                retryPolicy = retryPolicyStore.getRetryPolicy(p.partner);
+            if(p.restapiUrl.contains(",") && retryPolicy == null) {
+               String[] urls = p.restapiUrl.split(",");
+               retryPolicy = new RetryPolicy(urls,urls.length * 2);
+               p.restapiUrl = urls[0];
             }
             String pp = p.responsePrefix != null ? p.responsePrefix + '.' : "";
 
@@ -367,36 +410,20 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
             if (retryPolicy == null || !shouldRetry) {
                 setFailureResponseStatus(ctx, prefix, e.getMessage(), r);
             } else {
-                if (retryCount == null) {
-                    retryCount = 0;
-                }
-                String retryMessage = retryCount + " attempts were made out of " + retryPolicy.getMaximumRetries() +
-                    " maximum retries.";
-                log.debug(retryMessage);
+                log.debug(retryPolicy.getRetryMessage());
                 try {
-                    retryCount = retryCount + 1;
-                    if (retryCount < retryPolicy.getMaximumRetries() + 1) {
-                        URI uri = new URI(paramMap.get(restapiUrlString));
-                        String hostname = uri.getHost();
-                        String retryString = retryPolicy.getNextHostName(uri.toString());
-                        URI uriTwo = new URI(retryString);
-                        URI retryUri = UriBuilder.fromUri(uri).host(uriTwo.getHost()).port(uriTwo.getPort()).scheme(
-                            uriTwo.getScheme()).build();
-                        paramMap.put(restapiUrlString, retryUri.toString());
-                        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);
+                    //calling getNextHostName increments the retry count so it should be called before shouldRetry
+                    String retryString = retryPolicy.getNextHostName();
+                    if (retryPolicy.shouldRetry()) {
+                        paramMap.put(restapiUrlString, retryString);
+                        log.debug("retry attempt {} will use the retry url {}", retryPolicy.getRetryCount(), retryString);
+                        sendRequest(paramMap, ctx, retryPolicy);
                     } else {
-                        log.debug("Maximum retries reached, calling setFailureResponseStatus.");
+                        log.debug("Maximum retries reached, won't attempt to retry. Calling setFailureResponseStatus.");
                         setFailureResponseStatus(ctx, prefix, e.getMessage(), r);
                     }
                 } catch (Exception ex) {
-                    log.error("Could not attempt retry.", ex);
-                    String retryErrorMessage =
-                        "Retry attempt has failed. No further retry shall be attempted, calling " +
-                            "setFailureResponseStatus.";
+                    String retryErrorMessage = "Retry attempt " + retryPolicy.getRetryCount() + "has failed with error message " + ex.getMessage();
                     setFailureResponseStatus(ctx, prefix, retryErrorMessage, r);
                 }
             }
@@ -407,6 +434,18 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
         }
     }
 
+    protected void handlePartner(Map<String, String> paramMap) {
+        String partner = paramMap.get("partner");
+           if (partner != null && partner.length() > 0) {
+               PartnerDetails details = partnerStore.get(partner);
+               paramMap.put(restapiUserKey, details.username);
+               paramMap.put(restapiPasswordKey, details.password);
+               if(paramMap.get(restapiUrlString) == null) {
+                   paramMap.put(restapiUrlString, details.url);
+               }
+           }   
+    }
+
     protected String buildXmlJsonRequest(SvcLogicContext ctx, String template, Format format)
         throws SvcLogicException {
         log.info("Building {} started", format);
@@ -571,6 +610,7 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
                     .builder(new ConsumerCredentials(p.oAuthConsumerKey, p.oAuthConsumerSecret))
                     .version(p.oAuthVersion).signatureMethod(p.oAuthSignatureMethod).feature().build();
                 client.register(oAuth1Feature);
+
             }
         } else {
             if (p.authtype == AuthType.DIGEST) {
@@ -636,13 +676,12 @@ public class RestapiCallNode implements SvcLogicJavaPlugin {
 
         WebTarget webTarget = addAuthType(client, p).target(p.restapiUrl);
 
-        log.info("Sending request:");
+        log.info("Sending request below to url " + p.restapiUrl);
         log.info(request);
         long t1 = System.currentTimeMillis();
 
         HttpResponse r = new HttpResponse();
         r.code = 200;
-
         String accept = p.accept;
         if(accept == null) {
             accept = p.format == Format.XML ? "application/xml" : "application/json";
index 54c86fe..65684d9 100644 (file)
  */
 
 package org.onap.ccsdk.sli.plugins.restapicall;
-
 public class RetryPolicy {
     private String[] hostnames;
     private Integer maximumRetries;
-
-    public RetryPolicy(String[] hostnames, Integer maximumRetries){
-        this.hostnames = hostnames;
-        this.maximumRetries = 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;
     }
-
     public Integer getMaximumRetries() {
-        return maximumRetries;
+       return maximumRetries;
+    }
+    public int getRetryCount() {
+       return retryCount;
+    }
+    public Boolean shouldRetry() {
+       return retryCount < maximumRetries + 1;
+    }
+    public String getRetryMessage() {
+       return retryCount + " retry attempts were made out of " + maximumRetries + " maximum retry attempts.";
     }
     
-    public String getNextHostName(String uri) throws RetryException {
-        Integer position = null;
-
-        for (int i = 0; i < hostnames.length; i++) {
-            if (uri.contains(hostnames[i])) {
-                position = i;
-                break;
-            }
-        }
-
-        if(position == null){
-            throw new RetryException("No match found for the provided uri[" + uri + "] " +
-                    "so the next host name could not be retreived");
-        }
-        position++;
-
-        if (position > hostnames.length - 1) {
-            position = 0;
-        }
-        return hostnames[position];
+    public String getNextHostName() throws RetryException {
+       retryCount++;
+       position++;
+       
+       if (position > hostnames.length - 1) {
+           position = 0;
+       }
+       return hostnames[position];
     }
-
-}
+}
\ No newline at end of file
diff --git a/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicyStore.java b/restapi-call-node/provider/src/main/java/org/onap/ccsdk/sli/plugins/restapicall/RetryPolicyStore.java
deleted file mode 100644 (file)
index f68b851..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-/*-
- * ============LICENSE_START=======================================================
- * openECOMP : SDN-C
- * ================================================================================
- * Copyright (C) 2017 AT&T Intellectual Property. All rights
- *                     reserved.
- * Modifications Copyright Â© 2018 IBM.
- * ================================================================================
- * 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=========================================================
- */
-
-package org.onap.ccsdk.sli.plugins.restapicall;
-
-import java.util.HashMap;
-
-public class RetryPolicyStore {
-    HashMap<String, RetryPolicy> retryPolicies;
-    public String proxyServers;
-
-    public RetryPolicyStore() {
-        retryPolicies = new HashMap<>();
-    }
-
-    public String getProxyServers() {
-        return proxyServers;
-    }
-
-    public void setProxyServers(String admServers) {
-        this.proxyServers = admServers;
-        String[] adminServersArray = admServers.split(",");
-        RetryPolicy adminPortalRetry = new RetryPolicy(adminServersArray, adminServersArray.length);
-        retryPolicies.put("dme2proxy", adminPortalRetry);
-    }
-    
-    public RetryPolicy getRetryPolicy(String policyName) {
-        return (this.retryPolicies.get(policyName));
-    }
-
-}
old mode 100644 (file)
new mode 100755 (executable)
index bdf67dc..0704d29
 
 package org.onap.ccsdk.sli.plugins.restapicall;
 
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.core.Is.is;
-import java.net.URI;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
 import java.util.HashMap;
 import java.util.Map;
+
 import org.codehaus.jettison.json.JSONObject;
 import org.glassfish.grizzly.http.server.HttpServer;
 import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
 import org.glassfish.jersey.media.multipart.MultiPartFeature;
 import org.glassfish.jersey.server.ResourceConfig;
+
 import org.junit.Test;
 import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
 import org.onap.ccsdk.sli.core.sli.SvcLogicException;
@@ -40,9 +43,9 @@ import org.slf4j.LoggerFactory;
 
 public class TestRestapiCallNode {
 
+    @SuppressWarnings("unused")
     private static final Logger log = LoggerFactory.getLogger(TestRestapiCallNode.class);
 
-
     @Test
     public void testDelete() throws SvcLogicException {
         SvcLogicContext ctx = new SvcLogicContext();
@@ -64,7 +67,6 @@ public class TestRestapiCallNode {
 
         ctx.setAttribute("prop.name", "site1");
 
-
         Map<String, String> p = new HashMap<>();
         p.put("templateFileName", "src/test/resources/sdwan-site.json");
         p.put("restapiUrl", "https://echo.getpostman.com/delete");
@@ -77,61 +79,6 @@ public class TestRestapiCallNode {
         rcn.sendRequest(p, ctx);
     }
 
-    @Test
-    public void testJsonSdwanVpnTopologyTemplate() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        ctx.setAttribute("prop.topology", "topoType");
-
-        ctx.setAttribute("prop.roles_length", "1");
-        ctx.setAttribute("prop.roles[0]", "role1");
-
-        ctx.setAttribute("prop.siteAttachement_length", "2");
-
-        ctx.setAttribute("prop.siteAttachement[0].siteId", "site1");
-        ctx.setAttribute("prop.siteAttachement[0].roles_length", "0");
-        ctx.setAttribute("prop.siteAttachement[0].roles[0]", "role1");
-        ctx.setAttribute("prop.siteAttachement[0].roles[1]", "role3");
-
-        ctx.setAttribute("prop.siteAttachement[1].siteId", "site2");
-        ctx.setAttribute("prop.siteAttachement[1].roles_length", "1");
-        ctx.setAttribute("prop.siteAttachement[1].roles[0]", "role2");
-
-        Map<String, String> p = new HashMap<>();
-        p.put("templateFileName", "src/test/resources/sdwan-vpn-topology.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
-    public void testJsonSdwanSiteTemplate() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        ctx.setAttribute("prop.name", "site1");
-
-
-        Map<String, String> p = new HashMap<>();
-        p.put("templateFileName", "src/test/resources/sdwan-site.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
     public void testJsonTemplate() throws SvcLogicException {
         SvcLogicContext ctx = new SvcLogicContext();
@@ -250,33 +197,6 @@ public class TestRestapiCallNode {
         rcn.sendRequest(p, ctx);
     }
 
-    @Test(expected = SvcLogicException.class)
-    public void testFormData() 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<>();
-        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");
-        p.put("multipartFormData", "true");
-        p.put("multipartFile", "src/test/resources/test-template.json");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
 
     @Test(expected = SvcLogicException.class)
     public void testWithInvalidURI() throws SvcLogicException {
@@ -525,202 +445,74 @@ public class TestRestapiCallNode {
         RestapiCallNode rcn = new RestapiCallNode();
         rcn.sendRequest(p, ctx);
     }
-
-    @Test
-    public void testDeleteOAuthType() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("oAuthSignatureMethod", "plainTEXT");
-        p.put("oAuthVersion", "1.0");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test
-    public void testDeleteAuthTypeBasic() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "basic");
-        p.put("restapiUser", "admin");
-        p.put("restapiPassword", "admin123");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test
-    public void testDeleteAuthTypeDigest() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "digest");
-        p.put("restapiUser", "admin");
-        p.put("restapiPassword", "admin123");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test
-    public void testDeleteAuthTypeOAuth() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "oauth");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("oAuthSignatureMethod", "plainTEXT");
-        p.put("oAuthVersion", "1.0");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test
-    public void testDeleteAuthTypeNoneOAuth() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("oAuthSignatureMethod", "plainTEXT");
-        p.put("oAuthVersion", "1.0");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-    @Test
-    public void testDeleteAuthTypeNoneBasic() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("restapiUser", "admin");
-        p.put("restapiPassword", "admin123");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test(expected = SvcLogicException.class)
-    public void testInvalidDeleteAuthTypeOAuth() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "oauth");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test(expected = SvcLogicException.class)
-    public void testInvalidDeleteAuthTypeBasic() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "basic");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
-    @Test(expected = SvcLogicException.class)
-    public void testInvalidDeleteAuthTypeDigest() throws SvcLogicException {
-        SvcLogicContext ctx = new SvcLogicContext();
-
-        Map<String, String> p = new HashMap<>();
-        p.put("restapiUrl", "https://echo.getpostman.com/delete");
-        p.put("authType", "digest");
-        p.put("oAuthConsumerKey", "f2a1ed52710d4533bde25be6da03b6e3");
-        p.put("oAuthConsumerSecret", "secret");
-        p.put("httpMethod", "delete");
-        p.put("format", "none");
-        p.put("skipSending", "true");
-
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-    }
-
+    /*
+     * {
+  "partnerOne": {
+    "url": "http://localhost:7001"                                                                                                                                                             4 http://uebsb93kcdc.it.att.com:3904",
+    "test": "/metrics"
+  },
+  "partnerTwo": {
+    "url": "http://localhost:7002",
+    "user": "controller_user",
+    "password": "P@ssword",
+    "test": "/metrics"
+  },
+  "partnerThree": {
+    "url": "http://localhost:7003",
+    "user": "controller_admin"
+  }
+}
+     */
     @Test
-    public void testMultipartFormData() throws SvcLogicException {
-        final ResourceConfig resourceConfig = new ResourceConfig(
-                MultipartServerMock.class, MultiPartFeature.class);
-        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
-                URI.create("http://localhost:8080/"),resourceConfig);
+    public void testPartners() throws Exception{
+       String partnerTwoKey = "partnerTwo";
+       String partnerTwoUsername = "controller_user";
+       String partnerTwoPassword = "P@ssword";
 
-        Map<String, String> p = new HashMap<>();
-        p.put("multipartFormData", "true");
-        p.put("format", "none");
-        p.put("multipartFile", "src/test/resources/test-template.json");
-        p.put("restapiUrl", "http://localhost:8080/file-upload/upload");
-
-        SvcLogicContext ctx = new SvcLogicContext();
+       System.setProperty("SDNC_CONFIG_DIR", "src/test/resources");
         RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-        assertThat(ctx.getAttribute("response-code"), is("200"));
-        assertThat(ctx.getAttribute("httpResponse"), is( "test-template.json"));
-        server.shutdownNow();
+        assertNull(rcn.partnerStore.get("partnerOne"));
+        PartnerDetails details = rcn.partnerStore.get(partnerTwoKey);
+        assertEquals(partnerTwoUsername,details.username);
+        assertEquals(partnerTwoPassword,details.password);
+        assertNull(rcn.partnerStore.get("partnerThree"));
+        
+        //In this scenario the caller expects username, password and url to be picked up from the partners json
+        Map<String, String> paramMap = new HashMap<String,String>();
+        paramMap.put("partner", partnerTwoKey);
+       rcn.handlePartner(paramMap );
+        assertEquals(partnerTwoUsername,paramMap.get(rcn.restapiUserKey));
+        assertEquals(partnerTwoPassword,paramMap.get(rcn.restapiPasswordKey));
+        assertEquals("http://localhost:7002",paramMap.get(rcn.restapiUrlString));
+
+        //In this scenario the caller expects username, password and url to be picked up from the partners json
+        //the provided suffix will be appended to the default url from the partners json
+        paramMap = new HashMap<String,String>();
+        paramMap.put("partner", partnerTwoKey);
+        paramMap.put("restapiUrlSuffix", "/networking/v1/instance/3");
+       rcn.handlePartner(paramMap);
+       Parameters p = new Parameters();
+       RestapiCallNode.getParameters(paramMap, p);
+        assertEquals(partnerTwoUsername,p.restapiUser);
+        assertEquals(partnerTwoPassword,p.restapiPassword);
+        assertEquals("http://localhost:7002/networking/v1/instance/3",p.restapiUrl);
     }
-
+    
     @Test
-    public void testCookieResponse() throws SvcLogicException {
-        final ResourceConfig resourceConfig = new ResourceConfig(
-                MockCookieAuthServer.class);
-        HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
-                URI.create("http://localhost:8080/"),resourceConfig);
-
-        Map<String, String> p = new HashMap<>();
-        p.put("format", "none");
-        p.put("httpMethod", "get");
-        p.put("restapiUrl", "http://localhost:8080/get-cookie/cookie");
-        p.put("dumpHeaders", "true");
-
-        SvcLogicContext ctx = new SvcLogicContext();
-        RestapiCallNode rcn = new RestapiCallNode();
-        rcn.sendRequest(p, ctx);
-        assertThat(ctx.getAttribute("response-code"), is("200"));
-        assertThat(ctx.getAttribute("header.Set-Cookie"), is("cookieResponse=cookieValueInReturn;Version=1"));
-        server.shutdownNow();
+    public void retryPolicyBean() throws Exception {
+       Integer retries = 3;
+       String first = "http://localhost:7001";
+       String second = "http://localhost:7001";
+
+       RetryPolicy p = new RetryPolicy(new String[] {first,second}, retries);
+       assertEquals(retries,p.getMaximumRetries());
+       assertNotNull(p.getRetryMessage());
+       String next = p.getNextHostName();
+       assertEquals(second,next);
+       assertEquals(1,p.getRetryCount());
+       next = p.getNextHostName();
+       assertEquals(first,next);
+       assertEquals(2,p.getRetryCount());
     }
 
     @Test
diff --git a/restapi-call-node/provider/src/test/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java b/restapi-call-node/provider/src/test/org/onap/ccsdk/sli/plugins/restapicall/TestRestapiCallNode.java
new file mode 100755 (executable)
index 0000000..5037127
--- /dev/null
@@ -0,0 +1,511 @@
+/*-
+ * ============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=========================================================
+ */
+
+package org.onap.ccsdk.sli.plugins.restapicall;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.HashMap;
+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;
+
+public class TestRestapiCallNode {
+
+    @SuppressWarnings("unused")
+    private static final Logger log = LoggerFactory.getLogger(TestRestapiCallNode.class);
+
+
+    @Test
+    public void testDelete() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+
+        Map<String, String> p = new HashMap<>();
+        p.put("restapiUrl", "https://echo.getpostman.com/delete");
+        p.put("restapiUser", "user1");
+        p.put("restapiPassword", "pwd1");
+        p.put("httpMethod", "delete");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testDeleteWithPayload() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+
+        ctx.setAttribute("prop.name", "site1");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/sdwan-site.json");
+        p.put("restapiUrl", "https://echo.getpostman.com/delete");
+        p.put("restapiUser", "user1");
+        p.put("restapiPassword", "pwd1");
+        p.put("httpMethod", "delete");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    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");
+        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");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].source-uid", "APIDOC-123");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].action", "delete");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].request-timestamp", "2016-09-09 16:30:35.0");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].request-status", "New");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].processing-status", "New");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].service-clfi", "testClfi1");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[1].clci", "clci");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].source-uid", "APIDOC-123");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].action", "delete");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].request-timestamp", "2016-09-09 16:30:35.0");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].request-status", "New");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].processing-status", "New");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].service-clfi", "testClfi1");
+        ctx.setAttribute("tmp.sdn-circuit-req-row[2].clci", "clci");
+
+        Map<String, String> 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
+    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<>();
+        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<>();
+        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<>();
+        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<>();
+        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
+    public void testVpnJsonTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.l3vpn.name", "10000000-0000-0000-0000-000000000001");
+        ctx.setAttribute("prop.l3vpn.topology", "point_to_point");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l3smvpntemplate.json");
+        p.put("restapiUrl", "http://ipwan:18002/restconf/data/huawei-ac-net-l3vpn-svc:l3vpn-svc-cfg/vpn-services");
+        p.put("restapiUser", "admin");
+        p.put("restapiPassword", "admin123");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testSiteJsonTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.l3vpn.name", "10000000-0000-0000-0000-000000000001");
+        ctx.setAttribute("prop.l3vpn.topology", "point_to_point");
+
+        ctx.setAttribute("prop.l3vpn.site1_name", "10000000-0000-0000-0000-000000000002");
+        ctx.setAttribute("prop.l3vpn.vpn-policy1-id", "10000000-0000-0000-0000-000000000003");
+        ctx.setAttribute("prop.l3vpn.entry1-id", "1");
+        ctx.setAttribute("prop.l3vpn.sna1_name", "10000000-0000-0000-0000-000000000004");
+        ctx.setAttribute("prop.l3vpn.pe1_id", "a8098c1a-f86e-11da-bd1a-00112444be1e");
+        ctx.setAttribute("prop.l3vpn.ac1_id", "a8098c1a-f86e-11da-bd1a-00112444be1b");
+        ctx.setAttribute("prop.l3vpn.ac1-peer-ip", "192.168.1.1");
+        ctx.setAttribute("prop.l3vpn.ac1-ip", "192.168.1.2");
+        ctx.setAttribute("prop.l3vpn.sna1_svlan", "100");
+        ctx.setAttribute("prop.l3vpn.ac1_protocol", "static");
+        ctx.setAttribute("prop.l3vpn.sna1-route.ip-prefix", "192.168.1.1/24");
+        ctx.setAttribute("prop.l3vpn.sna1-route.next-hop", "192.168.1.4");
+
+        ctx.setAttribute("prop.l3vpn.site2_name", "10000000-0000-0000-0000-000000000005");
+        ctx.setAttribute("prop.l3vpn.vpn-policy2-id", "10000000-0000-0000-0000-000000000006");
+        ctx.setAttribute("prop.l3vpn.entry2-id", "1");
+        ctx.setAttribute("prop.l3vpn.sna2_name", "10000000-0000-0000-0000-000000000007");
+        ctx.setAttribute("prop.l3vpn.pe2_id", "a8098c1a-f86e-11da-bd1a-00112444be1a");
+        ctx.setAttribute("prop.l3vpn.ac2_id", "a8098c1a-f86e-11da-bd1a-00112444be1c");
+        ctx.setAttribute("prop.l3vpn.ac2-peer-ip", "192.168.1.6");
+        ctx.setAttribute("prop.l3vpn.ac2-ip", "192.168.1.5");
+        ctx.setAttribute("prop.l3vpn.sna2_svlan", "200");
+        ctx.setAttribute("prop.l3vpn.ac2_protocol", "bgp");
+        ctx.setAttribute("prop.l3vpn.peer2-ip", "192.168.1.7");
+        ctx.setAttribute("prop.l3vpn.ac2_protocol_bgp_as", "200");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l3smsitetemplate.json");
+        p.put("restapiUrl", "http://ipwan:18002/restconf/data/huawei-ac-net-l3vpn-svc:l3vpn-svc-cfg/sites");
+        p.put("restapiUser", "admin");
+        p.put("restapiPassword", "admin123");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testVrfJsonTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.l3vpn.vrf1-id", "10000000-0000-0000-0000-000000000007");
+        ctx.setAttribute("prop.l3vpn.vpn-policy1-id", "10000000-0000-0000-0000-000000000003");
+        ctx.setAttribute("prop.l3vpn.pe1_id", "a8098c1a-f86e-11da-bd1a-00112444be1e");
+        ctx.setAttribute("prop.l3vpn.vrf2-id", "10000000-0000-0000-0000-000000000009");
+        ctx.setAttribute("prop.l3vpn.vpn-policy2-id", "10000000-0000-0000-0000-000000000006");
+        ctx.setAttribute("prop.l3vpn.pe2_id", "a8098c1a-f86e-11da-bd1a-00112444be1a");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l3smvrftemplate.json");
+        p.put("restapiUrl", "http://ipwan:18002/restconf/data/huawei-ac-net-l3vpn-svc:l3vpn-svc-cfg/vrf-attributes");
+        p.put("restapiUser", "admin");
+        p.put("restapiPassword", "admin123");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testDeleteVpnJsonTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.l3vpn.name", "10000000-0000-0000-0000-000000000001");
+        ctx.setAttribute("prop.l3vpn.topology", "point_to_point");
+
+        Map<String, String> p = new HashMap<>();
+        //p.put("templateFileName", "src/test/resources/l3smvpntemplate.json");
+        p.put("restapiUrl", "http://ipwan:18002/restconf/data/huawei-ac-net-l3vpn-svc:l3vpn-svc-cfg/vpn-services"
+            + "/vpnservice=10000000-0000-0000-0000-000000000001");
+        p.put("restapiUser", "admin");
+        p.put("restapiPassword", "admin123");
+        p.put("format", "json");
+        p.put("httpMethod", "delete");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testL2DciTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.dci-connects.id", "Id1");
+        ctx.setAttribute("prop.dci-connects.name", "Name1");
+        ctx.setAttribute("prop.dci-connects.local_networks[0]", "NetId1");
+        ctx.setAttribute("prop.dci-connects.local_networks[1]", "NetId2");
+        ctx.setAttribute("prop.dci-connects.evpn_irts[0]", "100:1");
+        ctx.setAttribute("prop.dci-connects.evpn_erts[0]", "100:2");
+        ctx.setAttribute("prop.dci-connects.evpn_irts[1]", "200:1");
+        ctx.setAttribute("prop.dci-connects.evpn_erts[1]", "200:2");
+        ctx.setAttribute("prop.dci-connects.vni", "1");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l2-dci-connects-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
+    public void testL3DciTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.dci-connects.id", "Id1");
+        ctx.setAttribute("prop.dci-connects.name", "Name1");
+        ctx.setAttribute("prop.dci-connects.local_networks_length", "2");
+        ctx.setAttribute("prop.dci-connects.local_networks[0]", "NetId1");
+        ctx.setAttribute("prop.dci-connects.local_networks[1]", "NetId2");
+        ctx.setAttribute("prop.dci-connects.evpn_irts[0]", "100:1");
+        ctx.setAttribute("prop.dci-connects.evpn_erts[0]", "100:2");
+        ctx.setAttribute("prop.dci-connects.evpn_irts[1]", "200:1");
+        ctx.setAttribute("prop.dci-connects.evpn_erts[1]", "200:2");
+        ctx.setAttribute("prop.dci-connects.vni", "1");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l3-dci-connects-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
+    public void testControllerTokenTemplate() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.sdncRestApi.thirdpartySdnc.user", "admin");
+        ctx.setAttribute("prop.sdncRestApi.thirdpartySdnc.password", "admin123");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/actokentemplate.json");
+        p.put("restapiUrl", "https://ipwan:18002/controller/v2/tokens");
+        p.put("format", "json");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+
+    @Test
+    public void testDeleteNoneAsContentType() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+
+        Map<String, String> p = new HashMap<>();
+        p.put("restapiUrl", "https://echo.getpostman.com/delete");
+        p.put("restapiUser", "user1");
+        p.put("restapiPassword", "pwd1");
+        p.put("httpMethod", "delete");
+        p.put("format", "none");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+
+    @Test
+    public void testPostNoneAsContentType() throws SvcLogicException {
+        SvcLogicContext ctx = new SvcLogicContext();
+        ctx.setAttribute("prop.l3vpn.name", "10000000-0000-0000-0000-000000000001");
+        ctx.setAttribute("prop.l3vpn.topology", "point_to_point");
+
+        Map<String, String> p = new HashMap<>();
+        p.put("templateFileName", "src/test/resources/l3smvpntemplate.json");
+        p.put("restapiUrl", "http://ipwan:18002/restconf/data/huawei-ac-net-l3vpn-svc:l3vpn-svc-cfg/vpn-services");
+        p.put("restapiUser", "admin");
+        p.put("restapiPassword", "admin123");
+        p.put("format", "none");
+        p.put("httpMethod", "post");
+        p.put("responsePrefix", "restapi-result");
+        p.put("skipSending", "true");
+
+        RestapiCallNode rcn = new RestapiCallNode();
+        rcn.sendRequest(p, ctx);
+    }
+    /*
+     * {
+  "partnerOne": {
+    "url": "http://localhost:7001"                                                                                                                                                             4 http://uebsb93kcdc.it.att.com:3904",
+    "test": "/metrics"
+  },
+  "partnerTwo": {
+    "url": "http://localhost:7002",
+    "user": "controller_user",
+    "password": "P@ssword",
+    "test": "/metrics"
+  },
+  "partnerThree": {
+    "url": "http://localhost:7003",
+    "user": "controller_admin"
+  }
+}
+     */
+    @Test
+    public void testPartners() throws Exception{
+       String partnerTwoKey = "partnerTwo";
+       String partnerTwoUsername = "controller_user";
+       String partnerTwoPassword = "P@ssword";
+
+       System.setProperty("SDNC_CONFIG_DIR", "src/test/resources");
+        RestapiCallNode rcn = new RestapiCallNode();
+        assertNull(rcn.partnerStore.get("partnerOne"));
+        PartnerDetails details = rcn.partnerStore.get(partnerTwoKey);
+        assertEquals(partnerTwoUsername,details.username);
+        assertEquals(partnerTwoPassword,details.password);
+        assertNull(rcn.partnerStore.get("partnerThree"));
+        
+        //In this scenario the caller expects username, password and url to be picked up from the partners json
+        Map<String, String> paramMap = new HashMap<String,String>();
+        paramMap.put("partner", partnerTwoKey);
+       rcn.handlePartner(paramMap );
+        assertEquals(partnerTwoUsername,paramMap.get(rcn.restapiUserKey));
+        assertEquals(partnerTwoPassword,paramMap.get(rcn.restapiPasswordKey));
+        assertEquals("http://localhost:7002",paramMap.get(rcn.restapiUrlString));
+
+        //In this scenario the caller expects username, password and url to be picked up from the partners json
+        //the provided suffix will be appended to the default url from the partners json
+        paramMap = new HashMap<String,String>();
+        paramMap.put("partner", partnerTwoKey);
+        paramMap.put("restapiUrlSuffix", "/networking/v1/instance/3");
+       rcn.handlePartner(paramMap);
+       Parameters p = new Parameters();
+       RestapiCallNode.getParameters(paramMap, p);
+        assertEquals(partnerTwoUsername,p.restapiUser);
+        assertEquals(partnerTwoPassword,p.restapiPassword);
+        assertEquals("http://localhost:7002/networking/v1/instance/3",p.restapiUrl);
+    }
+    
+    @Test
+    public void retryPolicyBean() throws Exception {
+       Integer retries = 3;
+       String first = "http://localhost:7001";
+       String second = "http://localhost:7001";
+
+       RetryPolicy p = new RetryPolicy(new String[] {first,second}, retries);
+       assertEquals(retries,p.getMaximumRetries());
+       assertNotNull(p.getRetryMessage());
+       String next = p.getNextHostName();
+       assertEquals(second,next);
+       assertEquals(1,p.getRetryCount());
+       next = p.getNextHostName();
+       assertEquals(first,next);
+       assertEquals(2,p.getRetryCount());
+    }
+}
diff --git a/restapi-call-node/provider/src/test/resources/partners.json b/restapi-call-node/provider/src/test/resources/partners.json
new file mode 100755 (executable)
index 0000000..9a17a1a
--- /dev/null
@@ -0,0 +1,16 @@
+{\r
+       "partnerOne": {\r
+               "url": "http://localhost:7001",\r
+               "test": "/metrics"\r
+       },\r
+       "partnerTwo": {\r
+               "url": "http://localhost:7002",\r
+               "user": "controller_user",\r
+               "password": "P@ssword",\r
+               "test": "/metrics"\r
+       },\r
+       "partnerThree": {\r
+               "url": "http://localhost:7003",\r
+               "user": "controller_admin"\r
+       }\r
+}\r
index ac0897e..620df28 100644 (file)
@@ -46,8 +46,6 @@ import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
 import org.onap.ccsdk.sli.plugins.restapicall.Format;
 import org.onap.ccsdk.sli.plugins.restapicall.HttpResponse;
 import org.onap.ccsdk.sli.plugins.restapicall.RestapiCallNode;
-import org.onap.ccsdk.sli.plugins.restapicall.RetryException;
-import org.onap.ccsdk.sli.plugins.restapicall.RetryPolicy;
 import org.onap.ccsdk.sli.plugins.restapicall.XmlParser;
 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializer;
 import org.onap.ccsdk.sli.plugins.yangserializers.dfserializer.DataFormatSerializerContext;
@@ -165,14 +163,9 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin {
     public void sendRequest(Map<String, String> paramMap, SvcLogicContext ctx,
                             Integer retryCount) throws SvcLogicException {
         RestapiCallNode rest = getRestapiCallNode();
-        RetryPolicy retryPolicy = null;
         HttpResponse r = new HttpResponse();
         try {
             YangParameters p = getYangParameters(paramMap);
-            if (p.partner != null) {
-                retryPolicy = rest.getRetryPolicyStore()
-                        .getRetryPolicy(p.partner);
-            }
 
             String pp = p.responsePrefix != null ? p.responsePrefix + '.' : "";
             Map<String, String> props = new HashMap<>((Map)ctx.toProperties());
@@ -215,30 +208,7 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin {
 
             log.error(REQ_ERR + e.getMessage(), e);
             String prefix = parseParam(paramMap, RES_PRE, false, null);
-            if (retryPolicy == null || !shouldRetry) {
-                setFailureResponseStatus(ctx, prefix, e.getMessage());
-            } else {
-                if (retryCount == null) {
-                    retryCount = 0;
-                }
-                log.debug(format(ATTEMPTS_MSG, retryCount,
-                                 retryPolicy.getMaximumRetries()));
-                try {
-                    retryCount = retryCount + 1;
-                    if (retryCount < retryPolicy.getMaximumRetries() + 1) {
-                        setRetryUri(paramMap, retryPolicy);
-                        log.debug(format(RETRY_COUNT, retryCount, retryPolicy
-                                .getMaximumRetries()));
-                        sendRequest(paramMap, ctx, retryCount);
-                    } else {
-                        log.debug(MAX_RETRY_ERR);
-                        setFailureResponseStatus(ctx, prefix, e.getMessage());
-                    }
-                } catch (Exception ex) {
-                    log.error(NO_MORE_RETRY, ex);
-                    setFailureResponseStatus(ctx, prefix, RETRY_FAIL);
-                }
-            }
+            setFailureResponseStatus(ctx, prefix, e.getMessage());
         }
 
         if (r != null && r.code >= 300) {
@@ -402,31 +372,6 @@ public class RestconfApiCallNode implements SvcLogicJavaPlugin {
         ctx.setAttribute(prefix + RES_MSG, res.message);
     }
 
-    /**
-     * Sets the retry URI to the param map from the retry policies different
-     * host.
-     *
-     * @param paramMap            parameter map
-     * @param retryPolicy         retry policy
-     * @throws URISyntaxException when new URI creation fails
-     * @throws RetryException     when retry policy cannot give another host
-     */
-    private void setRetryUri(Map<String, String> paramMap,
-                             RetryPolicy retryPolicy)
-            throws URISyntaxException, RetryException {
-        URI uri = new URI(paramMap.get(REST_API_URL));
-        String hostName = uri.getHost();
-        String retryString = retryPolicy.getNextHostName(uri.toString());
-
-        URI uriTwo = new URI(retryString);
-        URI retryUri = UriBuilder.fromUri(uri).host(uriTwo.getHost()).port(
-                uriTwo.getPort()).scheme(uriTwo.getScheme()).build();
-
-        paramMap.put(REST_API_URL, retryUri.toString());
-        log.debug(UPDATED_URL + retryUri.toString());
-        log.debug(format(COMM_FAIL, hostName, retryString));
-    }
-
     /**
      * Updates request message for JSON and XML data format, when the HTTP
      * method points it as PUT or PATCH.