ONOS-3810 augmenting Rest southbound protocol and provider for https and password based auth

Change-Id: I3e5f07ba6a751bc8a7637373c037a1910181f9ab
diff --git a/drivers/ciena/src/main/java/org/onosproject/drivers/ciena/PortDiscoveryCienaWaveserverImpl.java b/drivers/ciena/src/main/java/org/onosproject/drivers/ciena/PortDiscoveryCienaWaveserverImpl.java
index fe466ad..5e3a442 100644
--- a/drivers/ciena/src/main/java/org/onosproject/drivers/ciena/PortDiscoveryCienaWaveserverImpl.java
+++ b/drivers/ciena/src/main/java/org/onosproject/drivers/ciena/PortDiscoveryCienaWaveserverImpl.java
@@ -54,14 +54,20 @@
     private static final String NAME = "name";
     private static final String ADMIN_STATE = "admin-state";
 
-    private static final ArrayList<String> LINESIDE = Lists.newArrayList(
-            "1.1", "1.2", "12.1", "12.2");
+    private static final ArrayList<String> LINESIDE_PORT_ID = Lists.newArrayList(
+            "4", "48");
 
     private static final String GENERAL_PORT_REQUEST =
-            "yang-api/datastore/ws-ports?config=true&format=xml&depth=unbounded";
-    private static final String SPECIFIC_PORT_PATH = "yang-api/datastore/ws-ptps/ptp/";
+            "ws-ports?config=true&format=xml&depth=unbounded";
+    private static final String SPECIFIC_PORT_PATH = "ws-ptps/ptp/";
     private static final String SPECIFIC_PORT_CONFIG =
             "/ptp-config?config=true&format=xml&depth=unbounded";
+    //HTTP strings
+//    private static final String GENERAL_PORT_REQUEST =
+//            "/yang-api/datastore/ws-ports?config=true&format=xml&depth=unbounded";
+//    private static final String SPECIFIC_PORT_PATH = "/yang-api/datastore/ws-ptps/ptp/";
+//    private static final String SPECIFIC_PORT_CONFIG =
+//            "/ptp-config?config=true&format=xml&depth=unbounded";
 
 
     @Override
@@ -76,24 +82,35 @@
                 loadXml(controller.get(deviceId, GENERAL_PORT_REQUEST, XML));
         List<HierarchicalConfiguration> portsConfig =
                 XmlConfigParser.parseWaveServerCienaPorts(config);
-
         portsConfig.stream().forEach(sub -> {
+            String portId = sub.getString(PORT_ID);
             String name = sub.getString(NAME);
             SparseAnnotations annotations = DefaultAnnotations.builder()
-                    .set(AnnotationKeys.NAME, String.valueOf(name)).build();
-            if (LINESIDE.contains(name)) {
-                String wsportInfoRequest = SPECIFIC_PORT_PATH + sub.getLong(PORT_ID) +
+                    .set(AnnotationKeys.NAME, name).build();
+            if (LINESIDE_PORT_ID.contains(portId)) {
+                String wsportInfoRequest = SPECIFIC_PORT_PATH + portId +
                         SPECIFIC_PORT_CONFIG;
                 ports.add(XmlConfigParser.parseWaveServerCienaOchPorts(
                         sub.getLong(PORT_ID),
-                        toGbps(Long.parseLong(sub.getString(SPEED).replace(GBPS, EMPTY_STRING))),
+                        toGbps(Long.parseLong(sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
+                                                      .replace(" ", EMPTY_STRING))),
                         XmlConfigParser.loadXml(controller.get(deviceId, wsportInfoRequest, XML)),
                         annotations));
-            } else {
+                //adding corresponding opposite side port
+                ports.add(XmlConfigParser.parseWaveServerCienaOchPorts(
+                        sub.getLong(PORT_ID) + 1,
+                        toGbps(Long.parseLong(sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
+                                                      .replace(" ", EMPTY_STRING))),
+                        XmlConfigParser.loadXml(controller.get(deviceId, wsportInfoRequest, XML)),
+                        DefaultAnnotations.builder()
+                                .set(AnnotationKeys.NAME, name.replace(".1", ".2"))
+                                .build()));
+            } else if (!portId.equals("5") && !portId.equals("49")) {
                 //FIXME change when all optical types have two way information methods, see jira tickets
                 final int speed100GbpsinMbps = 100000;
                 CltSignalType cltType = toGbps(Long.parseLong(
-                        sub.getString(SPEED).replace(GBPS, EMPTY_STRING))) == speed100GbpsinMbps ?
+                        sub.getString(SPEED).replace(GBPS, EMPTY_STRING)
+                                .replace(" ", EMPTY_STRING))) == speed100GbpsinMbps ?
                         CltSignalType.CLT_100GBE : null;
                 ports.add(new OduCltPortDescription(PortNumber.portNumber(sub.getLong(PORT_ID)),
                                                     sub.getString(ADMIN_STATE).equals(ENABLED),
@@ -107,5 +124,6 @@
     private long toGbps(long speed) {
         return speed * 1000;
     }
+
 }
 
diff --git a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
index baf26cb..aa1b959 100644
--- a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
+++ b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/DefaultRestSBDevice.java
@@ -16,7 +16,9 @@
 
 package org.onosproject.protocol.rest;
 
+import com.google.common.base.MoreObjects;
 import com.google.common.base.Preconditions;
+import org.apache.commons.lang3.StringUtils;
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
 
@@ -34,18 +36,20 @@
     private final String password;
     private boolean isActive;
     private String protocol;
+    private String url;
 
     public DefaultRestSBDevice(IpAddress ip, int port, String name, String password,
-                               String protocol, boolean isActive) {
+                               String protocol, String url, boolean isActive) {
         Preconditions.checkNotNull(ip, "IP address cannot be null");
         Preconditions.checkArgument(port > 0, "Port address cannot be negative");
         Preconditions.checkNotNull(protocol, "protocol address cannot be null");
         this.ip = ip;
         this.port = port;
         this.name = name;
-        this.password = password;
+        this.password = StringUtils.isEmpty(password) ? null : password;
         this.isActive = isActive;
         this.protocol = protocol;
+        this.url = StringUtils.isEmpty(url) ? null : url;
     }
 
     @Override
@@ -89,6 +93,22 @@
     }
 
     @Override
+    public String url() {
+        return url;
+    }
+
+    @Override
+    public String toString() {
+        return MoreObjects.toStringHelper(this)
+                .add("url", url)
+                .add("protocol", protocol)
+                .add("name", name)
+                .add("port", port)
+                .add("ip", ip)
+                .toString();
+    }
+
+    @Override
     public boolean equals(Object obj) {
         if (obj == this) {
             return true;
diff --git a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
index 6b76989..abef64e 100644
--- a/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
+++ b/protocols/rest/api/src/main/java/org/onosproject/protocol/rest/RestSBDevice.java
@@ -79,4 +79,10 @@
      */
     String protocol();
 
+    /**
+     * Returns the url for the REST requests, to be used instead of IP and PORT.
+     *
+     * @return url
+     */
+    String url();
 }
diff --git a/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java b/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
index 0bc3545..0542dec 100644
--- a/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
+++ b/protocols/rest/ctl/src/main/java/org/onosproject/protocol/rest/ctl/RestSBControllerImpl.java
@@ -16,17 +16,22 @@
 
 package org.onosproject.protocol.rest.ctl;
 
+import com.google.common.collect.ImmutableMap;
 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.filter.HTTPBasicAuthFilter;
 import org.apache.commons.io.IOUtils;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.http.client.methods.HttpPatch;
+import org.apache.http.conn.ssl.AllowAllHostnameVerifier;
 import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
+import org.apache.http.ssl.SSLContextBuilder;
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
 import org.onosproject.protocol.rest.RestSBController;
@@ -40,6 +45,10 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -59,7 +68,9 @@
     private static final int STATUS_OK = Response.Status.OK.getStatusCode();
     private static final int STATUS_CREATED = Response.Status.CREATED.getStatusCode();
     private static final int STATUS_ACCEPTED = Response.Status.ACCEPTED.getStatusCode();
-    private static final String SLASH = "/";
+    private static final String HTTPS = "https";
+    private static final String AUTHORIZATION_PROPERTY = "authorization";
+    private static final String BASIC_AUTH_PREFIX = "Basic ";
 
     private final Map<DeviceId, RestSBDevice> deviceMap = new ConcurrentHashMap<>();
     Client client;
@@ -78,7 +89,7 @@
 
     @Override
     public Map<DeviceId, RestSBDevice> getDevices() {
-        return deviceMap;
+        return ImmutableMap.copyOf(deviceMap);
     }
 
     @Override
@@ -88,13 +99,8 @@
 
     @Override
     public RestSBDevice getDevice(IpAddress ip, int port) {
-        for (RestSBDevice device : deviceMap.values()) {
-            if (device.ip().equals(ip) &&
-                    device.port() == port) {
-                return device;
-            }
-        }
-        return null;
+        return deviceMap.values().stream().filter(v -> v.ip().equals(ip)
+                && v.port() == port).findFirst().get();
     }
 
     @Override
@@ -162,32 +168,44 @@
                 throw new IllegalArgumentException("Unsupported media type " + mediaType);
 
         }
-        return new ByteArrayInputStream(webResource.accept(type).get(ClientResponse.class)
-                                                .getEntity(String.class)
-                                                .getBytes(StandardCharsets.UTF_8));
+
+        ClientResponse s = webResource.accept(type).get(ClientResponse.class);
+        if (checkReply(s)) {
+            return new ByteArrayInputStream(s.getEntity(String.class)
+                                                    .getBytes(StandardCharsets.UTF_8));
+        }
+        return null;
     }
 
     @Override
     public boolean patch(DeviceId device, String request, InputStream payload, String mediaType) {
-        String url = deviceMap.get(device).protocol() + COLON +
-                DOUBLESLASH +
-                deviceMap.get(device).ip().toString() +
-                COLON + deviceMap.get(device).port() +
-                SLASH + request;
         try {
-            HttpPatch httprequest = new HttpPatch(url);
+            log.debug("Url request {} ", getUrlString(device, request));
+            HttpPatch httprequest = new HttpPatch(getUrlString(device, request));
+            if (deviceMap.get(device).password() != null) {
+                String userPassword = deviceMap.get(device).name() + COLON + deviceMap.get(device).password();
+                String base64string = Base64.getEncoder().encodeToString(userPassword.getBytes(StandardCharsets.UTF_8));
+                httprequest.addHeader(AUTHORIZATION_PROPERTY, BASIC_AUTH_PREFIX + base64string);
+            }
             if (payload != null) {
                 StringEntity input = new StringEntity(IOUtils.toString(payload, StandardCharsets.UTF_8));
                 input.setContentType(mediaType);
                 httprequest.setEntity(input);
             }
-            int responseStatusCode = HttpClients.createDefault().execute(httprequest)
+            CloseableHttpClient httpClient;
+            if (deviceMap.containsKey(device) && deviceMap.get(device).protocol().equals(HTTPS)) {
+                httpClient = getApacheSslBypassClient();
+            } else {
+                httpClient = HttpClients.createDefault();
+            }
+            int responseStatusCode = httpClient
+                    .execute(httprequest)
                     .getStatusLine()
                     .getStatusCode();
             return checkStatusCode(responseStatusCode);
-        } catch (IOException e) {
-            log.error("Cannot do PATCH {} request on device {} because can't read payload",
-                      request, device);
+        } catch (IOException | NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
+            log.error("Cannot do PATCH {} request on device {}",
+                      request, device, e);
         }
         return false;
     }
@@ -212,11 +230,35 @@
     }
 
     private WebResource getWebResource(DeviceId device, String request) {
-        return Client.create().resource(deviceMap.get(device).protocol() + COLON +
-                                                DOUBLESLASH +
-                                                deviceMap.get(device).ip().toString() +
-                                                COLON + deviceMap.get(device).port() +
-                                                SLASH + request);
+        log.debug("Sending request to URL {} ", getUrlString(device, request));
+        WebResource webResource = client.resource(getUrlString(device, request));
+        if (deviceMap.containsKey(device) && deviceMap.get(device).password() != null) {
+            client.addFilter(new HTTPBasicAuthFilter(deviceMap.get(device).name(),
+                                                     deviceMap.get(device).password()));
+        }
+        return webResource;
+    }
+
+    //FIXME security issue: this trusts every SSL certificate, even if is self-signed. Also deprecated methods.
+    private CloseableHttpClient getApacheSslBypassClient() throws NoSuchAlgorithmException,
+            KeyManagementException, KeyStoreException {
+        return HttpClients.custom().
+                setHostnameVerifier(new AllowAllHostnameVerifier()).
+                setSslcontext(new SSLContextBuilder()
+                                      .loadTrustMaterial(null, (arg0, arg1) -> true)
+                                      .build()).build();
+    }
+
+    private String getUrlString(DeviceId device, String request) {
+        if (deviceMap.get(device).url() != null) {
+            return deviceMap.get(device).protocol() + COLON + DOUBLESLASH
+                    + deviceMap.get(device).url() + request;
+        } else {
+            return deviceMap.get(device).protocol() + COLON +
+                    DOUBLESLASH +
+                    deviceMap.get(device).ip().toString() +
+                    COLON + deviceMap.get(device).port() + request;
+        }
     }
 
     private boolean checkReply(ClientResponse response) {
@@ -233,7 +275,7 @@
                 statusCode == STATUS_ACCEPTED) {
             return true;
         } else {
-            log.error("Failed request: HTTP error code : "
+            log.error("Failed request, HTTP error code : "
                               + statusCode);
             return false;
         }
diff --git a/protocols/rest/ctl/src/test/java/org/onosproject/protocol/rest/ctl/RestSBControllerImplTest.java b/protocols/rest/ctl/src/test/java/org/onosproject/protocol/rest/ctl/RestSBControllerImplTest.java
index ab01cac..c7f809d 100644
--- a/protocols/rest/ctl/src/test/java/org/onosproject/protocol/rest/ctl/RestSBControllerImplTest.java
+++ b/protocols/rest/ctl/src/test/java/org/onosproject/protocol/rest/ctl/RestSBControllerImplTest.java
@@ -39,8 +39,8 @@
     public void setUp() {
         controller = new RestSBControllerImpl();
         controller.activate();
-        device1 = new DefaultRestSBDevice(IpAddress.valueOf("127.0.0.1"), 8080, "foo", "bar", "http", true);
-        device2 = new DefaultRestSBDevice(IpAddress.valueOf("127.0.0.2"), 8080, "foo1", "bar2", "http", true);
+        device1 = new DefaultRestSBDevice(IpAddress.valueOf("127.0.0.1"), 8080, "foo", "bar", "http", null, true);
+        device2 = new DefaultRestSBDevice(IpAddress.valueOf("127.0.0.2"), 8080, "foo1", "bar2", "http", null, true);
         controller.addDevice(device1);
     }
 
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
index 76f5abd..18c376b 100644
--- a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProvider.java
@@ -49,9 +49,14 @@
 import org.onosproject.protocol.rest.RestSBDevice;
 import org.slf4j.Logger;
 
+import javax.net.ssl.HttpsURLConnection;
 import java.io.IOException;
 import java.net.HttpURLConnection;
 import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Base64;
 import java.util.HashSet;
 import java.util.Set;
 
@@ -71,6 +76,10 @@
     private static final String PROVIDER = "org.onosproject.provider.rest.device";
     private static final String IPADDRESS = "ipaddress";
     private static final int TEST_CONNECT_TIMEOUT = 1000;
+    private static final String HTTPS = "https";
+    private static final String AUTHORIZATION_PROPERTY = "authorization";
+    private static final String BASIC_AUTH_PREFIX = "Basic ";
+    private static final String URL_SEPARATOR = "://";
     private final Logger log = getLogger(getClass());
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
@@ -202,7 +211,7 @@
         } catch (ConfigException e) {
             log.error("Configuration error {}", e);
         }
-        log.info("REST Devices {}", controller.getDevices());
+        log.debug("REST Devices {}", controller.getDevices());
         controller.getDevices().keySet().forEach(deviceId -> {
             DriverHandler h = driverService.createHandler(deviceId);
             PortDiscovery portConfig = h.behaviour(PortDiscovery.class);
@@ -216,14 +225,39 @@
 
     private boolean testDeviceConnection(RestSBDevice device) {
         try {
-            URL url = new URL(device.protocol(), device.ip().toString(), device.port(), "/");
-            HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
+            URL url;
+            if (device.url() == null) {
+                url = new URL(device.protocol(), device.ip().toString(), device.port(), "");
+            } else {
+                url = new URL(device.protocol() + URL_SEPARATOR + device.url());
+            }
+            HttpURLConnection urlConn;
+            if (device.protocol().equals(HTTPS)) {
+                //FIXME this method provides no security accepting all SSL certs.
+                RestDeviceProviderUtilities.enableSslCert();
+
+                urlConn = (HttpsURLConnection) url.openConnection();
+            } else {
+                urlConn = (HttpURLConnection) url.openConnection();
+            }
+            if (device.password() != null) {
+                String userPassword = device.name() + ":" + device.password();
+                String basicAuth = Base64.getEncoder()
+                        .encodeToString(userPassword.getBytes(StandardCharsets.UTF_8));
+                urlConn.setRequestProperty(AUTHORIZATION_PROPERTY, BASIC_AUTH_PREFIX + basicAuth);
+            }
             urlConn.setConnectTimeout(TEST_CONNECT_TIMEOUT);
-            boolean open = urlConn.getResponseCode() == (HttpURLConnection.HTTP_OK);
+            boolean open = urlConn.getResponseCode() == (HttpsURLConnection.HTTP_OK);
+            if (!open) {
+                log.error("Device {} not accessibile, response code {} ", device,
+                          urlConn.getResponseCode());
+            }
             urlConn.disconnect();
             return open;
-        } catch (IOException e) {
-            log.error("Device {} not reachable, error creating HTTP connection", device, e);
+
+        } catch (IOException | NoSuchAlgorithmException | KeyManagementException e) {
+            log.error("Device {} not reachable, error creating {} connection", device,
+                      device.protocol(), e);
         }
         return false;
     }
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProviderUtilities.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProviderUtilities.java
new file mode 100644
index 0000000..53c97e1
--- /dev/null
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceProviderUtilities.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2016 Open Networking Laboratory
+ *
+ * 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.
+ */
+
+package org.onosproject.provider.rest.device.impl;
+
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManager;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+/**
+ * Utilities class for RestDevice provider.
+ */
+final class RestDeviceProviderUtilities {
+
+    private static final String TLS = "TLS";
+
+    //disable construction.
+    private RestDeviceProviderUtilities(){}
+
+    /**
+     * Method that bypasses every SSL certificate verification and accepts every
+     * connection with any SSL protected device that ONOS has an interaction with.
+     * Needs addressing for secutirty purposes.
+     *
+     * @throws NoSuchAlgorithmException
+     * @throws KeyManagementException
+     */
+    //FIXME redo for security purposes.
+    protected static void enableSslCert() throws NoSuchAlgorithmException, KeyManagementException {
+        SSLContext ctx = SSLContext.getInstance(TLS);
+        ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
+        SSLContext.setDefault(ctx);
+        HttpsURLConnection.setDefaultHostnameVerifier((hostname, session) -> {
+            //FIXME better way to do this.
+            return true;
+        });
+    }
+
+    //FIXME this accepts every connection
+    private static class DefaultTrustManager implements X509TrustManager {
+
+        @Override
+        public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+        }
+
+        @Override
+        public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
+        }
+
+        @Override
+        public X509Certificate[] getAcceptedIssuers() {
+            return null;
+        }
+    }
+}
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
index 2056dce..3671922 100644
--- a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestProviderConfig.java
@@ -42,6 +42,7 @@
     private static final String NAME = "name";
     private static final String PASSWORD = "password";
     private static final String PROTOCOL = "protocol";
+    private static final String URL = "url";
 
     public Set<RestSBDevice> getDevicesAddresses() throws ConfigException {
         Set<RestSBDevice> devicesAddresses = Sets.newHashSet();
@@ -54,8 +55,10 @@
                 String name = node.path(NAME).asText();
                 String password = node.path(PASSWORD).asText();
                 String protocol = node.path(PROTOCOL).asText();
+                String url = node.path(URL).asText();
                 devicesAddresses.add(new DefaultRestSBDevice(ipAddr, port, name,
-                                                             password, protocol, false));
+                                                             password, protocol,
+                                                             url, false));
 
             }
         } catch (IllegalArgumentException e) {
diff --git a/tools/test/configs/restSB-cfg.json b/tools/test/configs/restSB-cfg.json
index b420f7c..944d40a 100644
--- a/tools/test/configs/restSB-cfg.json
+++ b/tools/test/configs/restSB-cfg.json
@@ -9,8 +9,8 @@
   "apps": {
     "org.onosproject.restsb": {
       "restDevices": [{
-        "name": "local",
-        "password": "local",
+        "name": "dev",
+        "password": "",
         "ip": "127.0.0.1",
         "port": 8080,
         "protocol": "http"