Add probeReachability API to the DeviceProvider

The new API is meant for probing the reachability of a device
and adds the ability to directly asses the result of the probe.

Change-Id: I310eba11b943208b5d6776fd8ccbc679d55dfb41
(cherry picked from commit d7cae13c11bdc6c9d344d362ecb71ad99df67367)
diff --git a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
index c91cfb2..6ce3269 100644
--- a/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
+++ b/providers/general/device/src/main/java/org/onosproject/provider/general/device/impl/GeneralDeviceProvider.java
@@ -421,6 +421,22 @@
         submitTask(deviceId, TaskType.CONNECTION_TEARDOWN);
     }
 
+    @Override
+    public CompletableFuture<Boolean> probeReachability(DeviceId deviceId) {
+        final DeviceHandshaker handshaker = getBehaviour(
+                deviceId, DeviceHandshaker.class);
+        if (handshaker == null) {
+            return CompletableFuture.completedFuture(false);
+        }
+        return handshaker.probeReachability();
+    }
+
+    private boolean probeReachabilitySync(DeviceId deviceId) {
+        // Wait 3/4 of the checkup interval
+        return Tools.futureGetOrElse(probeReachability(deviceId), (checkupInterval * 3000 / 4),
+                TimeUnit.MILLISECONDS, Boolean.FALSE);
+    }
+
     /**
      * Listener for configuration events.
      */
@@ -741,16 +757,12 @@
         // If here, device should be registered in the core.
         assertDeviceRegistered(deviceId);
 
-        if (!handshaker.isReachable()) {
+        if (!handshaker.isReachable() || !probeReachabilitySync(deviceId)) {
             // Device appears to be offline.
             markOfflineIfNeeded(deviceId);
-            // While we expect the protocol layer to implement some sort of
+            // We expect the protocol layer to implement some sort of
             // connection backoff mechanism and to signal availability via
-            // CHANNEL_OPEN events, we stimulate some channel activity now.
-            // Trigger probe over the network and forget about it (not waiting
-            // for future to complete). If channel is ready, we expect to come
-            // back here via a CHANNEL_OPEN event.
-            handshaker.probeReachability();
+            // CHANNEL_OPEN events.
             return;
         }