retry netconf ports discovery

Change-Id: If00ae3caec2a618002b31ab05e082ef97b3b793a
diff --git a/drivers/fujitsu/src/main/java/org/onosproject/drivers/fujitsu/FujitsuT100DeviceDescription.java b/drivers/fujitsu/src/main/java/org/onosproject/drivers/fujitsu/FujitsuT100DeviceDescription.java
index 8b8d170..5fc3a65 100644
--- a/drivers/fujitsu/src/main/java/org/onosproject/drivers/fujitsu/FujitsuT100DeviceDescription.java
+++ b/drivers/fujitsu/src/main/java/org/onosproject/drivers/fujitsu/FujitsuT100DeviceDescription.java
@@ -33,7 +33,6 @@
 import org.onosproject.net.device.PortDescription;
 import org.onosproject.net.driver.AbstractHandlerBehaviour;
 import org.onosproject.netconf.NetconfController;
-import org.onosproject.netconf.NetconfException;
 import org.onosproject.netconf.NetconfSession;
 import org.slf4j.Logger;
 
@@ -70,7 +69,8 @@
         try {
             reply = session.get(requestBuilder());
         } catch (IOException e) {
-            throw new RuntimeException(new NetconfException("Failed to retrieve configuration.", e));
+            log.error("Failed to retrieve port details for device {}", handler().data().deviceId());
+            return ImmutableList.of();
         }
         List<PortDescription> descriptions =
                 parseFujitsuT100Ports(XmlConfigParser.
diff --git a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
index 7305bba..96dd14f 100644
--- a/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
+++ b/providers/netconf/device/src/main/java/org/onosproject/provider/netconf/device/impl/NetconfDeviceProvider.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.provider.netconf.device.impl;
 
+import com.google.common.base.Objects;
 import com.google.common.base.Preconditions;
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -348,28 +349,42 @@
             boolean isReachable = isReachable(deviceId);
             if (isReachable && !deviceService.isAvailable(deviceId)) {
                 Device device = deviceService.getDevice(deviceId);
-                DeviceDescription updatedDeviceDescription = null;
                 if (device.is(DeviceDescriptionDiscovery.class)) {
                     if (mastershipService.isLocalMaster(deviceId)) {
                         DeviceDescriptionDiscovery deviceDescriptionDiscovery =
                                 device.as(DeviceDescriptionDiscovery.class);
-                        updatedDeviceDescription = deviceDescriptionDiscovery.discoverDeviceDetails();
+                        DeviceDescription updatedDeviceDescription = deviceDescriptionDiscovery.discoverDeviceDetails();
+                        if (updatedDeviceDescription != null &&
+                                !descriptionEquals(device, updatedDeviceDescription)) {
+                            providerService.deviceConnected(
+                                    deviceId, new DefaultDeviceDescription(
+                                            updatedDeviceDescription, true, updatedDeviceDescription.annotations()));
+                        }
+                        //if ports are not discovered, retry the discovery
+                        if (deviceService.getPorts(deviceId).isEmpty()) {
+                            discoverPorts(deviceId);
+                        }
                     }
                 } else {
                     log.warn("No DeviceDescriptionDiscovery behaviour for device {}", deviceId);
                 }
-                if (updatedDeviceDescription == null) {
-                    updatedDeviceDescription = deviceDescription;
-                }
-                providerService.deviceConnected(
-                        deviceId, new DefaultDeviceDescription(
-                                updatedDeviceDescription, true, updatedDeviceDescription.annotations()));
             } else if (!isReachable && deviceService.isAvailable(deviceId)) {
                 providerService.deviceDisconnected(deviceId);
             }
         }
     }
 
+    private boolean descriptionEquals(Device device, DeviceDescription updatedDeviceDescription) {
+        return Objects.equal(device.id(), updatedDeviceDescription.deviceUri())
+                && Objects.equal(device.type(), updatedDeviceDescription.type())
+                && Objects.equal(device.manufacturer(), updatedDeviceDescription.manufacturer())
+                && Objects.equal(device.hwVersion(), updatedDeviceDescription.hwVersion())
+                && Objects.equal(device.swVersion(), updatedDeviceDescription.swVersion())
+                && Objects.equal(device.serialNumber(), updatedDeviceDescription.serialNumber())
+                && Objects.equal(device.chassisId(), updatedDeviceDescription.chassisId())
+                && Objects.equal(device.annotations(), updatedDeviceDescription.annotations());
+    }
+
     private void checkAndUpdateDevices() {
         NetconfProviderConfig cfg = cfgService.getConfig(appId, NetconfProviderConfig.class);
         if (cfg != null) {