Merge "[CORD-2253] Update ONOS to 1.10.10"
diff --git a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
index fc118ed..9b18473 100644
--- a/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
+++ b/global/ce-orchestration/src/main/java/org/opencord/ce/global/orchestration/MetroOrchestrationManager.java
@@ -75,6 +75,7 @@
 import static org.opencord.ce.api.models.CarrierEthernetLogicalTerminationPoint.Role;
 import static org.opencord.ce.api.models.CarrierEthernetVirtualConnection.Type;
 import static org.onosproject.net.config.basics.SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY;
+import static org.opencord.ce.api.services.channel.Symbols.MEF_PORT_TYPE;
 import static org.slf4j.LoggerFactory.getLogger;
 
 /**
@@ -657,7 +658,10 @@
 
     @Override
     public void removeEvc(EvcConnId evcId) {
+        log.info("Received remove request of EVC, {}", evcId);
+        log.debug("existing EVCs {}", evcMap);
         if (evcMap.containsKey(evcId)) {
+            log.debug("EVC existing, removing, {}", evcId);
             CarrierEthernetVirtualConnection evc = evcMap.get(evcId);
             evc.fcSet().forEach(fc -> {
                 // Decrement the FC refCount to make removal possible
@@ -665,8 +669,12 @@
                 removeFc(fc.id());
             });
             // Avoid excessively incrementing EVC ids
-            nextEvcShortId = evc.shortId() < nextEvcShortId ? evc.shortId() : nextEvcShortId;
+            if (evc.shortId() != null) {
+                nextEvcShortId = evc.shortId() < nextEvcShortId ? evc.shortId() : nextEvcShortId;
+            }
             evcMap.remove(evcId);
+        } else {
+            log.info("EVC {} not present", evcId);
         }
     }
 
@@ -1109,42 +1117,20 @@
     }
 
     /**
-     * Validates whether the provided connect point can be associated with an LTP of the provided type.
-     *
-     * Conditions for validating the LTP type:
-     * - If UNI: ConnectPoint is not associated with any link
-     * - If INNI/ENNI: ConnectPoint is associated with a link
+     * Validates whether the provided connect point can be associated with an LTP of the provided type
+     * based on port annotation. This is consistent with how underlying domains configure
+     * Carrier Ethernet interfaces to expose to the global controller.
      *
      * @param cp the connect point associated with the LTP to be validated
      * @param ltpType the type of the LTP to be validated or null in case a type is to be decided by the method
      * @return the ltpType if validation succeeded, a new type depending on cp and topo, or null if validation failed
-     */
+     * */
     private CarrierEthernetNetworkInterface.Type validateLtpType(
             ConnectPoint cp, CarrierEthernetNetworkInterface.Type ltpType) {
-        if (linkService.getEgressLinks(cp).isEmpty() && linkService.getIngressLinks(cp).isEmpty()) {
-            // A connect point can be a UNI only if it doesn't belong to any link
-            if (ltpType == null) {
-                // If provided type is null, decide about the LTP type based on connectivity
-                return CarrierEthernetNetworkInterface.Type.UNI;
-            } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.UNI)) {
-                // Validate type
-                return ltpType;
-            } else {
-                return null;
-            }
-        } else {
-            // A connect point can be an INNI or ENNI only if it belongs to a link
-            if (ltpType == null) {
-                // If provided type is null, decide about the LTP type based on connectivity
-                return CarrierEthernetNetworkInterface.Type.INNI;
-            } else if (ltpType.equals(CarrierEthernetNetworkInterface.Type.INNI) ||
-                    ltpType.equals(CarrierEthernetNetworkInterface.Type.ENNI)) {
-                // Validate type
-                return ltpType;
-            } else {
-                return null;
-            }
-        }
+        Port port = deviceService.getPort(cp);
+        CarrierEthernetNetworkInterface.Type type = CarrierEthernetNetworkInterface.Type.valueOf(
+                port.annotations().value(MEF_PORT_TYPE));
+        return (type == ltpType) ? type : null;
     }
 
     @Override
diff --git a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
index a6687a1..4c17837 100644
--- a/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
+++ b/global/http-channel/src/main/java/org/opencord/ce/global/channel/client/HttpClientInstance.java
@@ -185,6 +185,7 @@
 
     @Override
     public void createBandwidthProfileResources(CarrierEthernetForwardingConstruct fc, CarrierEthernetUni uni) {
+        log.debug("FC {}, UNI {}", fc, uni);
         DomainId domainId = domainService.getDomain(uni.cp().deviceId());
         if (domainId == LOCAL || !isLeader(getTopic(domainId))) {
             return;
diff --git a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
index e67e804..8d8eb38 100644
--- a/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
+++ b/global/virtualprovider/src/main/java/org/opencord/ce/global/virtualdomain/VirtualDomainDeviceProvider.java
@@ -24,6 +24,7 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.Service;
 import org.onosproject.net.config.basics.SubjectFactories;
+import org.onosproject.net.device.DeviceService;
 import org.onosproject.store.service.AtomicCounter;
 import org.onosproject.store.service.StorageService;
 import org.opencord.ce.api.services.virtualprovider.DomainVirtualDevice;
@@ -67,6 +68,7 @@
 
 import java.util.List;
 import java.util.concurrent.ExecutorService;
+import java.util.stream.Collectors;
 
 import static java.util.concurrent.Executors.newFixedThreadPool;
 import static org.onlab.util.Tools.groupedThreads;
@@ -74,6 +76,7 @@
 import static org.onosproject.net.AnnotationKeys.LATITUDE;
 import static org.onosproject.net.AnnotationKeys.LONGITUDE;
 import static org.opencord.ce.api.services.channel.Symbols.MEF_PORT_TYPE;
+import static org.opencord.ce.api.services.channel.Symbols.UNI;
 import static org.slf4j.LoggerFactory.getLogger;
 import static org.opencord.ce.api.models.CarrierEthernetNetworkInterface.Type;
 
@@ -118,6 +121,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
     protected MetroOrchestrationService metroOrchestrationService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+    protected DeviceService deviceService;
+
     protected DeviceProviderService deviceProviderService;
 
     private EcordDriverConfig ecordDriverConfig;
@@ -274,11 +280,19 @@
      * @param portDescriptions description of ports
      */
     private void advertiseDevicePorts(DeviceId deviceId, List<PortDescription> portDescriptions) {
+        List<PortNumber> ports = deviceService.getPorts(deviceId).stream().map(Port::number)
+                .collect(Collectors.toList());
+        List<PortDescription> toNotify = portDescriptions.stream()
+                .filter(portDescription -> !ports.contains(portDescription.portNumber())
+                        && portDescription.annotations().value(MEF_PORT_TYPE).equalsIgnoreCase(UNI))
+                .collect(Collectors.toList());
         log.info("Notifying ecord virtual ports...");
+        log.debug("E-CORD virtual ports {}", portDescriptions);
         deviceProviderService.updatePorts(deviceId, portDescriptions);
        // addGlobalMefLtp(deviceId, portDescriptions);
         log.info("Notifying XOS of virtual ports...");
-        notifyXoS(deviceId, portDescriptions);
+        log.debug("E-CORD to XOS ports {}", toNotify);
+        notifyXoS(deviceId, toNotify);
     }
 
     private void disconnectDevice(DeviceId deviceId) {