Ports and port description are not cleared up properly upon removal

Change-Id: I4a2287e9ed29c9a423d7ae297c12736537191619
diff --git a/core/store/dist/src/main/java/org/onosproject/store/device/impl/DeviceDescriptions.java b/core/store/dist/src/main/java/org/onosproject/store/device/impl/DeviceDescriptions.java
index f14b062..bcebc61 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/device/impl/DeviceDescriptions.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/device/impl/DeviceDescriptions.java
@@ -104,4 +104,13 @@
         }
         portDescs.put(newOne.value().portNumber(), newOne);
     }
+
+    /**
+     * Removes PortDescription.
+     *
+     * @param portNumber the port to remove.
+     */
+    public void removePortDesc(PortNumber portNumber) {
+        portDescs.remove(portNumber);
+    }
 }
diff --git a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
index 885d6b0..5760e23 100644
--- a/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
+++ b/core/store/dist/src/main/java/org/onosproject/store/device/impl/GossipDeviceStore.java
@@ -685,7 +685,7 @@
                 }
 
                 if (isRemoved && oldPort != null) {
-                    events.add(removePort(deviceId, oldPort.number()));
+                    events.add(removePort(deviceId, oldPort.number(), providerId, descsMap));
                 } else if (!isRemoved) {
                     events.add(oldPort == null ?
                                        createPort(device, newPort, ports) :
@@ -724,11 +724,16 @@
         return null;
     }
 
-    private DeviceEvent removePort(DeviceId deviceId, PortNumber portNumber) {
+    private DeviceEvent removePort(DeviceId deviceId, PortNumber portNumber,
+                                   ProviderId providerId, Map<ProviderId, DeviceDescriptions> descsMap) {
 
         log.info("Deleted port: " + deviceId.toString() + "/" + portNumber.toString());
         Port deletedPort = devicePorts.get(deviceId).remove(portNumber);
 
+        descsMap.computeIfPresent(providerId, (provider, deviceDescriptions) -> {
+            deviceDescriptions.removePortDesc(portNumber);
+            return deviceDescriptions;
+        });
         return new DeviceEvent(PORT_REMOVED, getDevice(deviceId), deletedPort);
     }
 
@@ -803,12 +808,16 @@
         final Timestamped<PortDescription> deltaDesc
                 = new Timestamped<>(portDescription, newTimestamp);
         final DeviceEvent event;
-        final Timestamped<PortDescription> mergedDesc;
+        Timestamped<PortDescription> mergedDesc;
         final Map<ProviderId, DeviceDescriptions> device = getOrCreateDeviceDescriptionsMap(deviceId);
         synchronized (device) {
             event = updatePortStatusInternal(providerId, deviceId, deltaDesc);
             mergedDesc = device.get(providerId)
                     .getPortDesc(portDescription.portNumber());
+            //on delete the port is removed, thus using latest known description
+            if (mergedDesc == null) {
+                mergedDesc = new Timestamped<>(portDescription, newTimestamp);
+            }
         }
         if (event != null) {
             log.debug("Notifying peers of a port status update topology event for providerId: {} and deviceId: {}",
@@ -844,7 +853,7 @@
             final Port oldPort = ports.get(number);
             final Port newPort;
             final Timestamped<PortDescription> existingPortDesc = descs.getPortDesc(number);
-            boolean toDelete = false;
+            boolean toDelete;
 
             if (existingPortDesc == null ||
                     deltaDesc.isNewer(existingPortDesc)) {
@@ -859,10 +868,11 @@
                 return null;
             }
 
-            if (oldPort == null) {
-                return createPort(device, newPort, ports);
+            if (!toDelete) {
+                return oldPort == null ? createPort(device, newPort, ports) :
+                        updatePort(device, oldPort, newPort, ports);
             } else {
-                return toDelete ? removePort(deviceId, number) : updatePort(device, oldPort, newPort, ports);
+                return removePort(deviceId, number, providerId, descsMap);
             }
         }
     }
@@ -1111,6 +1121,8 @@
             removalRequest.put(deviceId, timestamp);
 
             Device device = devices.remove(deviceId);
+            //removing internal description
+            deviceDescs.remove(deviceId);
             // should DEVICE_REMOVED carry removed ports?
             Map<PortNumber, Port> ports = devicePorts.get(deviceId);
             if (ports != null) {