WIP removing sub based on programmed data

Change-Id: I1998e72e95bc70e1bf49625bced358843649a69e
diff --git a/impl/src/main/java/org/opencord/olt/impl/Olt.java b/impl/src/main/java/org/opencord/olt/impl/Olt.java
index d744c1e..e963997 100644
--- a/impl/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/impl/src/main/java/org/opencord/olt/impl/Olt.java
@@ -79,6 +79,8 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.locks.Lock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.stream.Collectors;
+import java.util.Optional;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
 import static org.onlab.util.Tools.get;
@@ -373,10 +375,23 @@
                 log.error("Subscriber on {} is not provisioned", accessDevicePort);
                 return false;
             }
-
-            SubscriberAndDeviceInformation si = subsService.get(getPortName(port));
+            SubscriberAndDeviceInformation si;
+            //First check if the subscriber is in the programmed subscriber map, if not fallback to sadis
+            List<Map.Entry<ServiceKey, UniTagInformation>> entries =
+                    oltFlowService.getProgrammedSubscribers().entrySet().stream()
+                            .filter(entry -> entry.getKey().getPort().equals(accessDevicePort))
+                            .collect(Collectors.toList());
+            if (!entries.isEmpty()) {
+                List<UniTagInformation> programmedList = entries.stream()
+                        .map(entry -> entry.getKey().getService())
+                        .collect(Collectors.toList());
+                si = new SubscriberAndDeviceInformation();
+                si.setUniTagList(programmedList);
+            } else {
+                si = subsService.get(getPortName(port));
+            }
             if (si == null) {
-                log.error("Subscriber information not found in sadis for port {}",
+                log.error("Subscriber information not found in programmed subscribers and sadis for port {}",
                         accessDevicePort);
                 // NOTE that we are returning true so that the subscriber is removed from the queue
                 // and we can move on provisioning others
@@ -389,6 +404,7 @@
             // regardless of the flow status
             si.uniTagList().forEach(uti -> {
                 ServiceKey sk = new ServiceKey(accessDevicePort, uti);
+                log.debug("Updating status for {} to false", sk);
                 oltFlowService.updateProvisionedSubscriberStatus(sk, false);
             });
 
@@ -413,7 +429,7 @@
         }
 
         SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
-        UniTagInformation specificService = getUniTagInformation(getPortName(port), cTag, sTag, tpId);
+        UniTagInformation specificService = getUniTagInformation(port, cTag, sTag, tpId);
         if (specificService == null) {
             log.error("Can't find Information for subscriber on {}, with cTag {}, " +
                     "stag {}, tpId {}", cp, cTag, sTag, tpId);
@@ -453,7 +469,7 @@
         }
 
         SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
-        UniTagInformation specificService = getUniTagInformation(getPortName(port), cTag, sTag, tpId);
+        UniTagInformation specificService = getUniTagInformation(port, cTag, sTag, tpId);
         if (specificService == null) {
             log.error("Can't find Information for subscriber on {}, with cTag {}, " +
                     "stag {}, tpId {}", cp, cTag, sTag, tpId);
@@ -616,16 +632,30 @@
      * using the pon c tag, pon s tag and the technology profile id
      * May return Optional<null>
      *
-     * @param portName  port of the subscriber
+     * @param port  port of the subscriber
      * @param innerVlan pon c tag
      * @param outerVlan pon s tag
      * @param tpId      the technology profile id
      * @return the found uni tag information
      */
-    private UniTagInformation getUniTagInformation(String portName, VlanId innerVlan,
+    private UniTagInformation getUniTagInformation(Port port, VlanId innerVlan,
                                                    VlanId outerVlan, int tpId) {
+        String portName = portWithName(port);
         log.debug("Getting uni tag information for {}, innerVlan: {}, outerVlan: {}, tpId: {}",
                 portName, innerVlan, outerVlan, tpId);
+        //First check if the subscriber is in the programmed subscriber map, if not fallback to sadis
+        //there should be only one sub service with these characteristics.
+        Optional<Map.Entry<ServiceKey, UniTagInformation>> service = oltFlowService.getProgrammedSubscribers()
+                .entrySet().stream()
+                .filter(entry -> entry.getKey().getPort().equals(new AccessDevicePort(port))
+                        && entry.getValue().getPonSTag().equals(outerVlan)
+                && entry.getValue().getPonCTag().equals(innerVlan))
+                .findFirst();
+        if (service.isPresent()) {
+            log.debug("Subscriber was programmed with " +
+                    "unit tag info for {}, {}, {}, {}", port, innerVlan, outerVlan, tpId);
+            return service.get().getValue();
+        }
         SubscriberAndDeviceInformation subInfo = subsService.get(portName);
         if (subInfo == null) {
             log.warn("Subscriber information doesn't exist for {}", portName);
@@ -637,23 +667,21 @@
             log.warn("Uni tag list is not found for the subscriber {} on {}", subInfo.id(), portName);
             return null;
         }
-
-        UniTagInformation service = OltUtils.getUniTagInformation(subInfo, innerVlan, outerVlan, tpId);
-
-        if (service == null) {
+        UniTagInformation uniTagInformation = OltUtils.getUniTagInformation(subInfo, innerVlan, outerVlan, tpId);
+        if (uniTagInformation == null) {
             // Try again after invalidating cache for the particular port name.
             subsService.invalidateId(portName);
             subInfo = subsService.get(portName);
-            service = OltUtils.getUniTagInformation(subInfo, innerVlan, outerVlan, tpId);
+            uniTagInformation = OltUtils.getUniTagInformation(subInfo, innerVlan, outerVlan, tpId);
         }
 
-        if (service == null) {
+        if (uniTagInformation == null) {
             log.warn("SADIS doesn't include the service with ponCtag {} ponStag {} and tpId {} on {}",
                     innerVlan, outerVlan, tpId, portName);
             return null;
         }
 
-        return service;
+        return uniTagInformation;
     }
 
     protected void bindSadisService(SadisService service) {