Attempt to fix Link vanishing after mastership change

- LLDPLinkProvider: handle DeviceUpdate event
- DeviceManager: publish Device events caused by Mastership change
- DeviceManager: Always try to markOffLine on deviceDisconnected
- GossipDeviceStore: Silently ignore failure to get Timestamp on port events

Change-Id: I51fbb3f1924007867512f20e62d6d53090c63640
diff --git a/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LLDPLinkProvider.java b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LLDPLinkProvider.java
index f024414..8e50378 100644
--- a/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LLDPLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onlab/onos/provider/lldp/impl/LLDPLinkProvider.java
@@ -111,11 +111,22 @@
                 log.error("Device is null.");
                 return;
             }
+            log.trace("{} {} {}", event.type(), event.subject(), event);
             switch (event.type()) {
                 case DEVICE_ADDED:
-                    discoverers.put(device.id(),
-                                    new LinkDiscovery(device, packetSevice, masterService,
-                                                      providerService, useBDDP));
+                case DEVICE_UPDATED:
+                    ld = discoverers.get(device.id());
+                    if (ld == null) {
+                        log.debug("Device added ({}) {}", event.type(), device.id());
+                        discoverers.put(device.id(),
+                               new LinkDiscovery(device, packetSevice, masterService,
+                                      providerService, useBDDP));
+                    } else {
+                        if (ld.isStopped()) {
+                            log.debug("Device restarted ({}) {}", event.type(), device.id());
+                            ld.start();
+                        }
+                    }
                     break;
                 case PORT_ADDED:
                 case PORT_UPDATED:
@@ -125,6 +136,7 @@
                             return;
                         }
                         if (!port.number().isLogical()) {
+                            log.debug("Port added {}", port);
                             ld.addPort(port);
                         }
                     } else {
@@ -134,12 +146,15 @@
                     }
                     break;
                 case PORT_REMOVED:
+                    log.debug("Port removed {}", port);
                     ConnectPoint point = new ConnectPoint(device.id(),
                                                           port.number());
                     providerService.linksVanished(point);
+                    // TODO: Don't we need to removePort from ld?
                     break;
                 case DEVICE_REMOVED:
                 case DEVICE_SUSPENDED:
+                    log.debug("Device removed {}", device.id());
                     ld = discoverers.get(device.id());
                     if (ld == null) {
                         return;
@@ -153,15 +168,18 @@
                         return;
                     }
                     if (deviceService.isAvailable(device.id())) {
+                        log.debug("Device up {}", device.id());
                         ld.start();
                     } else {
                         providerService.linksVanished(device.id());
+                        log.debug("Device down {}", device.id());
                         ld.stop();
                     }
                     break;
-                case DEVICE_UPDATED:
                 case DEVICE_MASTERSHIP_CHANGED:
                     if (!discoverers.containsKey(device.id())) {
+                        // TODO: ideally, should never reach here
+                        log.debug("Device mastership changed ({}) {}", event.type(), device.id());
                         discoverers.put(device.id(),
                                new LinkDiscovery(device, packetSevice, masterService,
                                       providerService, useBDDP));