Linc-OE ports now identifiable as Och and OMS ports.

Reference: ONOS-1803

Conflicts:
	utils/misc/src/main/java/org/onlab/util/Frequency.java

Change-Id: Ie2bdf74f8198afbd58a4762ff97bff6f4e9010df
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 24c21d0..fd7fcd8 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
@@ -28,6 +28,9 @@
 import org.onosproject.net.device.DefaultDeviceDescription;
 import org.onosproject.net.device.DefaultPortDescription;
 import org.onosproject.net.device.DeviceDescription;
+import org.onosproject.net.device.OchPortDescription;
+import org.onosproject.net.device.OduCltPortDescription;
+import org.onosproject.net.device.OmsPortDescription;
 import org.onosproject.net.device.PortDescription;
 import org.onosproject.store.Timestamp;
 import org.onosproject.store.impl.Timestamped;
@@ -97,9 +100,34 @@
         if (oldOne != null) {
             SparseAnnotations merged = union(oldOne.value().annotations(),
                                              newDesc.value().annotations());
-            newOne = new Timestamped<PortDescription>(
-                    new DefaultPortDescription(newDesc.value(), merged),
-                    newDesc.timestamp());
+            newOne = null;
+            switch (newDesc.value().type()) {
+                case OMS:
+                    OmsPortDescription omsDesc = (OmsPortDescription) (newDesc.value());
+                    newOne = new Timestamped<PortDescription>(
+                            new OmsPortDescription(
+                                    omsDesc, omsDesc.minFrequency(), omsDesc.maxFrequency(), omsDesc.grid(), merged),
+                            newDesc.timestamp());
+                    break;
+                case OCH:
+                    OchPortDescription ochDesc = (OchPortDescription) (newDesc.value());
+                    newOne = new Timestamped<PortDescription>(
+                            new OchPortDescription(
+                                    ochDesc, ochDesc.signalType(), ochDesc.isTunable(), ochDesc.lambda(), merged),
+                            newDesc.timestamp());
+                    break;
+                case ODUCLT:
+                    OduCltPortDescription ocDesc = (OduCltPortDescription) (newDesc.value());
+                    newOne = new Timestamped<PortDescription>(
+                            new OduCltPortDescription(
+                                    ocDesc, ocDesc.signalType(), merged),
+                            newDesc.timestamp());
+                    break;
+                default:
+                    newOne = new Timestamped<PortDescription>(
+                            new DefaultPortDescription(newDesc.value(), merged),
+                            newDesc.timestamp());
+            }
         }
         portDescs.put(newOne.value().portNumber(), newOne);
     }
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 8852c49..f7f459c 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
@@ -717,7 +717,6 @@
     public synchronized DeviceEvent updatePortStatus(ProviderId providerId,
                                                      DeviceId deviceId,
                                                      PortDescription portDescription) {
-
         final Timestamp newTimestamp;
         try {
             newTimestamp = deviceClockService.getTimestamp(deviceId);
@@ -1000,13 +999,14 @@
         // if no primary, assume not enabled
         boolean isEnabled = false;
         DefaultAnnotations annotations = DefaultAnnotations.builder().build();
-
+        Timestamp newest = null;
         final Timestamped<PortDescription> portDesc = primDescs.getPortDesc(number);
         if (portDesc != null) {
             isEnabled = portDesc.value().isEnabled();
             annotations = merge(annotations, portDesc.value().annotations());
+            newest = portDesc.timestamp();
         }
-
+        Port updated = null;
         for (Entry<ProviderId, DeviceDescriptions> e : descsMap.entrySet()) {
             if (e.getKey().equals(primary)) {
                 continue;
@@ -1019,30 +1019,35 @@
             // annotation merging. not so efficient, should revisit later
             final Timestamped<PortDescription> otherPortDesc = e.getValue().getPortDesc(number);
             if (otherPortDesc != null) {
+                if (newest != null && newest.isNewerThan(otherPortDesc.timestamp())) {
+                    continue;
+                }
                 annotations = merge(annotations, otherPortDesc.value().annotations());
+                switch (otherPortDesc.value().type()) {
+                    case OMS:
+                        OmsPortDescription omsPortDesc = (OmsPortDescription) otherPortDesc.value();
+                        updated = new OmsPort(device, number, isEnabled, omsPortDesc.minFrequency(),
+                                omsPortDesc.maxFrequency(), omsPortDesc.grid());
+                        break;
+                    case OCH:
+                        OchPortDescription ochPortDesc = (OchPortDescription) otherPortDesc.value();
+                        updated = new OchPort(device, number, isEnabled, ochPortDesc.signalType(),
+                                ochPortDesc.isTunable(), ochPortDesc.lambda(), annotations);
+                        break;
+                    case ODUCLT:
+                        OduCltPortDescription oduCltPortDesc = (OduCltPortDescription) otherPortDesc.value();
+                        updated = new OduCltPort(device, number, isEnabled, oduCltPortDesc.signalType(), annotations);
+                        break;
+                    default:
+                        updated = new DefaultPort(device, number, isEnabled, annotations);
+                }
+                newest = otherPortDesc.timestamp();
             }
         }
-
         if (portDesc == null) {
-            return new DefaultPort(device, number, false, annotations);
+            return updated == null ? new DefaultPort(device, number, false, annotations) : updated;
         }
-
-        switch (portDesc.value().type()) {
-            case OMS:
-                OmsPortDescription omsPortDesc = (OmsPortDescription) portDesc.value();
-                return new OmsPort(device, number, isEnabled, omsPortDesc.minFrequency(),
-                        omsPortDesc.maxFrequency(), omsPortDesc.grid());
-            case OCH:
-                OchPortDescription ochPortDesc = (OchPortDescription) portDesc.value();
-                return new OchPort(device, number, isEnabled, ochPortDesc.signalType(),
-                        ochPortDesc.isTunable(), ochPortDesc.lambda(), annotations);
-            case ODUCLT:
-                OduCltPortDescription oduCltPortDesc = (OduCltPortDescription) portDesc.value();
-                return new OduCltPort(device, number, isEnabled, oduCltPortDesc.signalType(), annotations);
-            default:
-                return new DefaultPort(device, number, isEnabled, portDesc.value().type(),
-                        portDesc.value().portSpeed(), annotations);
-        }
+        return updated == null ? new DefaultPort(device, number, isEnabled, annotations) : updated;
     }
 
     /**