added OAuth2 authentication for REST protocol

Change-Id: I3b8f3943ea043587730870a0b861760a4d6f3aa7
diff --git a/providers/rest/BUCK b/providers/rest/BUCK
index 81fe5b4..b6e2e2b 100644
--- a/providers/rest/BUCK
+++ b/providers/rest/BUCK
@@ -3,6 +3,7 @@
     '//protocols/rest/api:onos-protocols-rest-api',
     '//protocols/rest/ctl:onos-protocols-rest-ctl',
     '//lib:jersey-client',
+    '//lib:jersey-security',
     '//lib:commons-io',
     '//lib:httpclient-osgi',
     '//lib:httpcore-osgi',
diff --git a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java
index 648e56a..cd290e5 100644
--- a/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java
+++ b/providers/rest/device/src/main/java/org/onosproject/provider/rest/device/impl/RestDeviceConfig.java
@@ -21,6 +21,7 @@
 import org.onlab.packet.IpAddress;
 import org.onosproject.net.DeviceId;
 import org.onosproject.net.config.Config;
+import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
 
 /**
  * Configuration to push devices to the REST provider.
@@ -38,11 +39,14 @@
     private static final String MANUFACTURER = "manufacturer";
     private static final String HWVERSION = "hwVersion";
     private static final String SWVERSION = "swVersion";
+    private static final String AUTHENTICATION_SCHEME = "authenticationScheme";
+    private static final String TOKEN = "token";
 
     @Override
     public boolean isValid() {
         return hasOnlyFields(IP, PORT, USERNAME, PASSWORD, PROTOCOL, URL,
-                             TESTURL, MANUFACTURER, HWVERSION, SWVERSION) &&
+                TESTURL, MANUFACTURER, HWVERSION, SWVERSION, AUTHENTICATION_SCHEME,
+                TOKEN) &&
                 ip() != null;
     }
 
@@ -136,6 +140,31 @@
         return get(SWVERSION, "");
     }
 
+    /**
+     * Gets the authentication type of the REST device.
+     * Default is 'basic' if username is defined, else default is no_authentication.
+     *
+     * @return authentication
+     */
+    public AuthenticationScheme authenticationScheme() {
+        // hack for backward compatibility
+        if (!hasField(AUTHENTICATION_SCHEME)) {
+            if (hasField(USERNAME)) {
+                return AuthenticationScheme.BASIC;
+            }
+        }
+        return AuthenticationScheme.valueOf(get(AUTHENTICATION_SCHEME, "NO_AUTHENTICATION").toUpperCase());
+    }
+
+    /**
+     * Gets the token of the REST device.
+     *
+     * @return token
+     */
+    public String token() {
+        return get(TOKEN, "");
+    }
+
     private Pair<String, Integer> extractIpPort() {
         String info = subject.toString();
         if (info.startsWith(RestDeviceProvider.REST)) {
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 091dc34..7f6d9e8 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
@@ -28,8 +28,6 @@
 import org.onlab.util.SharedScheduledExecutors;
 import org.onosproject.core.ApplicationId;
 import org.onosproject.core.CoreService;
-import org.onosproject.net.behaviour.PortAdmin;
-import org.onosproject.net.config.ConfigException;
 import org.onosproject.net.AnnotationKeys;
 import org.onosproject.net.DefaultAnnotations;
 import org.onosproject.net.Device;
@@ -38,7 +36,9 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.SparseAnnotations;
 import org.onosproject.net.behaviour.DevicesDiscovery;
+import org.onosproject.net.behaviour.PortAdmin;
 import org.onosproject.net.behaviour.PortDiscovery;
+import org.onosproject.net.config.ConfigException;
 import org.onosproject.net.config.ConfigFactory;
 import org.onosproject.net.config.NetworkConfigEvent;
 import org.onosproject.net.config.NetworkConfigListener;
@@ -73,6 +73,7 @@
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -81,7 +82,6 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.stream.Collectors;
-import java.util.concurrent.CompletableFuture;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 import static org.onlab.util.Tools.groupedThreads;
@@ -354,22 +354,25 @@
         Set<DeviceId> deviceSubjects =
                 cfgService.getSubjects(DeviceId.class, RestDeviceConfig.class);
         connectDevices(deviceSubjects.stream()
-                               .filter(deviceId -> deviceService.getDevice(deviceId) == null)
-                               .map(deviceId -> {
-                                   RestDeviceConfig config =
-                                           cfgService.getConfig(deviceId, RestDeviceConfig.class);
-                                   return new DefaultRestSBDevice(config.ip(),
-                                                                  config.port(),
-                                                                  config.username(),
-                                                                  config.password(),
-                                                                  config.protocol(),
-                                                                  config.url(),
-                                                                  false,
-                                                                  config.testUrl(),
-                                                                  config.manufacturer(),
-                                                                  config.hwVersion(),
-                                                                  config.swVersion());
-                               }).collect(Collectors.toSet()));
+                .filter(deviceId -> deviceService.getDevice(deviceId) == null)
+                .map(deviceId -> {
+                    RestDeviceConfig config =
+                            cfgService.getConfig(deviceId, RestDeviceConfig.class);
+                    return new DefaultRestSBDevice(config.ip(),
+                            config.port(),
+                            config.username(),
+                            config.password(),
+                            config.protocol(),
+                            config.url(),
+                            false,
+                            config.testUrl(),
+                            config.manufacturer(),
+                            config.hwVersion(),
+                            config.swVersion(),
+                            config.authenticationScheme(),
+                            config.token()
+                    );
+                }).collect(Collectors.toSet()));
     }
 
     //Old method to register devices provided via net-cfg under apps/rest/ tree
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 e04be6f..21d9774 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
@@ -21,15 +21,17 @@
 import com.google.common.collect.Sets;
 import org.onlab.packet.IpAddress;
 import org.onosproject.core.ApplicationId;
-import org.onosproject.net.config.ConfigException;
 import org.onosproject.net.config.Config;
+import org.onosproject.net.config.ConfigException;
 import org.onosproject.protocol.rest.DefaultRestSBDevice;
 import org.onosproject.protocol.rest.RestSBDevice;
+import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;
 
 import java.util.Set;
 
 /**
  * Configuration for RestSB provider.
+ *
  * @deprecated 1.10.0 Kingfisher. Please Use RestDeviceConfig
  */
 @Deprecated
@@ -48,6 +50,8 @@
     private static final String MANUFACTURER = "manufacturer";
     private static final String HWVERSION = "hwVersion";
     private static final String SWVERSION = "swVersion";
+    private static final String AUTHENTICATION_SCHEME = "authenticationScheme";
+    private static final String TOKEN = "token";
 
     public Set<RestSBDevice> getDevicesAddresses() throws ConfigException {
         Set<RestSBDevice> devicesAddresses = Sets.newHashSet();
@@ -65,11 +69,14 @@
                 String manufacturer = node.path(MANUFACTURER).asText();
                 String hwVersion = node.path(HWVERSION).asText();
                 String swVersion = node.path(SWVERSION).asText();
+                AuthenticationScheme authenticationScheme = AuthenticationScheme.valueOf(node.path(
+                        AUTHENTICATION_SCHEME).asText().toUpperCase());
+                String token = node.path(TOKEN).asText();
 
                 devicesAddresses.add(new DefaultRestSBDevice(ipAddr, port, username,
-                                                             password, protocol,
-                                                             url, false, testUrl, manufacturer,
-                                                             hwVersion, swVersion));
+                        password, protocol,
+                        url, false, testUrl, manufacturer,
+                        hwVersion, swVersion, authenticationScheme, token));
             }
         } catch (IllegalArgumentException e) {
             throw new ConfigException(CONFIG_VALUE_ERROR, e);