Fix lldpProvider:
- when staleAge is not used
- prevent discovery being cancelled

Change-Id: If5e2b4d6c4020b2ab909ba71a536068438581d7b
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
index b99e4be..24d9a33 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
@@ -741,14 +741,24 @@
                     if (isStale(e.getValue())) {
                         if (useStaleLinkAge) {
                             providerService.linkVanished(new DefaultLinkDescription(e.getKey().src(),
-
                                                                                 e.getKey().dst(),
                                                                                 DIRECT));
                             return true;
                         }
-                        log.warn("VanishStaleLinkAge feature is disabled, " +
-                                "not bringing down link src {} dst {} with expired StaleLinkAge",
-                                e.getKey().src(), e.getKey().dst());
+                        // if one of the device is not available - let's prune the link
+                        if (!deviceService.isAvailable(e.getKey().src().deviceId()) ||
+                                !deviceService.isAvailable(e.getKey().dst().deviceId())) {
+                            return true;
+                        }
+                        // if one of the ports is not enable - let's prune the link
+                        Port srcPort = deviceService.getPort(e.getKey().src());
+                        Port dstPort = deviceService.getPort(e.getKey().dst());
+                        if (!srcPort.isEnabled() || !dstPort.isEnabled()) {
+                            return true;
+                        }
+                        log.trace("VanishStaleLinkAge feature is disabled, " +
+                                        "not bringing down link src {} dst {} with expired StaleLinkAge",
+                                 e.getKey().src(), e.getKey().dst());
                     }
                     return false;
                 }).clear();
diff --git a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
index e743af5..578e1c1 100644
--- a/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
+++ b/providers/lldpcommon/src/main/java/org/onosproject/provider/lldpcommon/LinkDiscovery.java
@@ -370,17 +370,30 @@
      */
     @Override
     public void run(Timeout t) {
-        if (isStopped()) {
-            return;
-        }
-
-        if (context.mastershipService().isLocalMaster(deviceId)) {
-            log.trace("Sending probes from {}", deviceId);
-            ImmutableMap.copyOf(portMap).forEach(this::sendProbes);
-        }
-
-        if (!isStopped()) {
-            timeout = t.timer().newTimeout(this, context.probeRate(), MILLISECONDS);
+        try {
+            // Check first if it has been stopped
+            if (isStopped()) {
+                return;
+            }
+            // Verify if we are still the master
+            if (context.mastershipService().isLocalMaster(deviceId)) {
+                log.trace("Sending probes from {}", deviceId);
+                ImmutableMap.copyOf(portMap).forEach(this::sendProbes);
+            }
+        } catch (Exception e) {
+            // Catch all exceptions to avoid timer task being cancelled
+            if (!isStopped()) {
+                // Error condition
+                log.error("Exception thrown during link discovery process", e);
+            } else {
+                // Provider is shutting down, the error can be ignored
+                log.trace("Shutting down, ignoring error", e);
+            }
+        } finally {
+            // if it has not been stopped - re-schedule itself
+            if (!isStopped()) {
+                timeout = t.timer().newTimeout(this, context.probeRate(), MILLISECONDS);
+            }
         }
     }