SEBA-1009-Minor version upgrade

Change-Id: I3fff2718ed28842872773fa0a93f73f127545f2f
diff --git a/api/pom.xml b/api/pom.xml
index bfd1ad8..e5e8954 100644
--- a/api/pom.xml
+++ b/api/pom.xml
@@ -26,6 +26,7 @@
         <relativePath>../pom.xml</relativePath>
     </parent>
 
+    <version>${olt.api.version}</version>
     <artifactId>olt-api</artifactId>
     <packaging>bundle</packaging>
 
diff --git a/app/app.xml b/app/app.xml
index 53e8767..da3f106 100644
--- a/app/app.xml
+++ b/app/app.xml
@@ -19,9 +19,10 @@
      category="Traffic Steering" url="http://onosproject.org"
      title="Optical Line Terminal App"
      featuresRepo="mvn:${project.groupId}/${project.artifactId}/${project.version}/xml/features"
-     features="${project.artifactId}" apps="org.opencord.sadis">
+     features="${project.artifactId}">
     <description>${project.description}</description>
-    <artifact>mvn:${project.groupId}/olt-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/olt-api/${olt.api.version}</artifact>
     <artifact>mvn:${project.groupId}/olt-impl/${project.version}</artifact>
     <artifact>mvn:${project.groupId}/olt-web/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/sadis-api/${sadis.api.version}</artifact>
 </app>
diff --git a/app/features.xml b/app/features.xml
index abb171b..d63d0d7 100644
--- a/app/features.xml
+++ b/app/features.xml
@@ -18,8 +18,9 @@
     <feature name="${project.artifactId}" version="${project.version}"
              description="${project.description}">
         <feature>onos-api</feature>
-        <bundle>mvn:${project.groupId}/olt-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/olt-api/${olt.api.version}</bundle>
         <bundle>mvn:${project.groupId}/olt-impl/${project.version}</bundle>
         <bundle>mvn:${project.groupId}/olt-web/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/sadis-api/${sadis.api.version}</bundle>
     </feature>
 </features>
diff --git a/app/pom.xml b/app/pom.xml
index 2682ae2..4d28a44 100644
--- a/app/pom.xml
+++ b/app/pom.xml
@@ -38,7 +38,6 @@
         <onos.app.readme>
             CORD OLT Access management application
         </onos.app.readme>
-        <olt.api.version>${project.version}</olt.api.version>
     </properties>
 
     <build>
diff --git a/impl/pom.xml b/impl/pom.xml
index 99f4b4e..ad2c90b 100644
--- a/impl/pom.xml
+++ b/impl/pom.xml
@@ -29,10 +29,6 @@
     <packaging>bundle</packaging>
     <description>OLT application for CORD</description>
 
-    <properties>
-        <olt.api.version>${project.version}</olt.api.version>
-    </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.opencord</groupId>
@@ -82,6 +78,13 @@
             <scope>provided</scope>
         </dependency>
 
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+            <version>2.10.2</version>
+            <scope>provided</scope>
+        </dependency>
+
     </dependencies>
 
     <build>
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 24073b0..b95bc08 100644
--- a/impl/src/main/java/org/opencord/olt/impl/Olt.java
+++ b/impl/src/main/java/org/opencord/olt/impl/Olt.java
@@ -68,6 +68,7 @@
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
 
 import java.util.ArrayList;
@@ -80,8 +81,6 @@
 import java.util.Set;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -112,6 +111,7 @@
 public class Olt
         extends AbstractListenerManager<AccessDeviceEvent, AccessDeviceListener>
         implements AccessDeviceService {
+    private static final String SADIS_NOT_RUNNING = "Sadis is not running.";
     private static final String APP_NAME = "org.opencord.olt";
 
     private static final short EAPOL_DEFAULT_VLAN = 4091;
@@ -132,8 +132,11 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected CoreService coreService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected SadisService sadisService;
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            bind = "bindSadisService",
+            unbind = "unbindSadisService",
+            policy = ReferencePolicy.DYNAMIC)
+    protected volatile SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected AccessDeviceFlowService oltFlowService;
@@ -198,7 +201,7 @@
     private ConsistentMultimap<ConnectPoint, UniTagInformation> programmedSubs;
     private ConsistentMultimap<ConnectPoint, UniTagInformation> failedSubs;
 
-    private ConcurrentMap<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingSubscribersForDevice;
+    protected Map<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingSubscribersForDevice;
 
     @Activate
     public void activate(ComponentContext context) {
@@ -215,6 +218,8 @@
         KryoNamespace serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
                 .register(UniTagInformation.class)
+                .register(SubscriberFlowInfo.class)
+                .register(LinkedBlockingQueue.class)
                 .build();
 
         programmedSubs = storageService.<ConnectPoint, UniTagInformation>consistentMultimapBuilder()
@@ -229,11 +234,19 @@
                 .withApplicationId(appId)
                 .build();
 
-        pendingSubscribersForDevice = new ConcurrentHashMap<>();
+        pendingSubscribersForDevice = storageService.<DeviceId, BlockingQueue<SubscriberFlowInfo>>consistentMapBuilder()
+                .withName("volt-pending-subs")
+                .withSerializer(Serializer.using(serializer))
+                .withApplicationId(appId)
+                .build().asJavaMap();
         eventDispatcher.addSink(AccessDeviceEvent.class, listenerRegistry);
 
-        subsService = sadisService.getSubscriberInfoService();
-        bpService = sadisService.getBandwidthProfileService();
+        if (sadisService != null) {
+            subsService = sadisService.getSubscriberInfoService();
+            bpService = sadisService.getBandwidthProfileService();
+        } else {
+            log.warn(SADIS_NOT_RUNNING);
+        }
 
         List<NodeId> readyNodes = clusterService.getNodes().stream()
                 .filter(c -> clusterService.getState(c.id()) == ControllerNode.State.READY)
@@ -292,6 +305,20 @@
         }
     }
 
+    protected void bindSadisService(SadisService service) {
+        sadisService = service;
+        bpService = sadisService.getBandwidthProfileService();
+        subsService = sadisService.getSubscriberInfoService();
+        log.info("Sadis-service binds to onos.");
+    }
+
+    protected void unbindSadisService(SadisService service) {
+        sadisService = null;
+        bpService = null;
+        subsService = null;
+        log.info("Sadis-service unbinds from onos.");
+    }
+
     @Override
     public boolean provisionSubscriber(ConnectPoint connectPoint) {
         log.info("Call to provision subscriber at {}", connectPoint);
@@ -590,6 +617,10 @@
      * @return the context of the bandwidth profile information
      */
     private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
+        if (bpService == null) {
+            log.warn(SADIS_NOT_RUNNING);
+            return null;
+        }
         if (bandwidthProfile == null) {
             return null;
         }
@@ -826,6 +857,7 @@
             }
         }
     }
+
     private void checkAndCreateDevMeter(DeviceId deviceId, BandwidthProfileInformation bwpInfo) {
         //If false the meter is already being installed, skipping installation
         if (!oltMeterService.checkAndAddPendingMeter(deviceId, bwpInfo)) {
@@ -851,6 +883,7 @@
                     SubscriberFlowInfo fi = queue.peek();
                     if (fi == null) {
                         log.debug("No more subscribers pending on {}", deviceId);
+                        pendingSubscribersForDevice.replace(deviceId, queue);
                         break;
                     }
                     if (result == null) {
@@ -891,6 +924,7 @@
         });
 
     }
+
     /**
      * Add subscriber flows given meter information for both upstream and
      * downstream directions.
@@ -1100,7 +1134,11 @@
      * @param cp ConnectPoint on which to find the subscriber
      * @return subscriber if found else null
      */
-    SubscriberAndDeviceInformation getSubscriber(ConnectPoint cp) {
+    protected SubscriberAndDeviceInformation getSubscriber(ConnectPoint cp) {
+        if (subsService == null) {
+            log.warn(SADIS_NOT_RUNNING);
+            return null;
+        }
         Port port = deviceService.getPort(cp);
         checkNotNull(port, "Invalid connect point");
         String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
@@ -1137,6 +1175,10 @@
      * @return the olt information
      */
     private SubscriberAndDeviceInformation getOltInfo(Device dev) {
+        if (subsService == null) {
+            log.warn(SADIS_NOT_RUNNING);
+            return null;
+        }
         String devSerialNo = dev.serialNumber();
         return subsService.get(devSerialNo);
     }
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
index 14fa4f9..adaeeba 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OltFlowService.java
@@ -21,6 +21,7 @@
 import org.onlab.packet.MacAddress;
 import org.onlab.packet.TpPort;
 import org.onlab.packet.VlanId;
+import org.onlab.util.KryoNamespace;
 import org.onlab.util.Tools;
 import org.onosproject.cfg.ComponentConfigService;
 import org.onosproject.core.ApplicationId;
@@ -46,6 +47,9 @@
 import org.onosproject.net.flowobjective.ObjectiveContext;
 import org.onosproject.net.flowobjective.ObjectiveError;
 import org.onosproject.net.meter.MeterId;
+import org.onosproject.store.serializers.KryoNamespaces;
+import org.onosproject.store.service.Serializer;
+import org.onosproject.store.service.StorageService;
 import org.opencord.olt.internalapi.AccessDeviceFlowService;
 import org.opencord.olt.internalapi.AccessDeviceMeterService;
 import org.opencord.sadis.BandwidthProfileInformation;
@@ -60,14 +64,14 @@
 import org.osgi.service.component.annotations.Modified;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
 import org.slf4j.Logger;
 
 import java.util.Dictionary;
+import java.util.Map;
 import java.util.Properties;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import static com.google.common.base.Strings.isNullOrEmpty;
@@ -88,7 +92,7 @@
         DEFAULT_TP_ID + ":Integer=" + DEFAULT_TP_ID_DEFAULT
 })
 public class OltFlowService implements AccessDeviceFlowService {
-
+    private static final String SADIS_NOT_RUNNING = "Sadis is not running.";
     private static final String APP_NAME = "org.opencord.olt";
     private static final int NONE_TP_ID = -1;
     private static final int NO_PCP = -1;
@@ -112,8 +116,11 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected MastershipService mastershipService;
 
-    @Reference(cardinality = ReferenceCardinality.MANDATORY)
-    protected SadisService sadisService;
+    @Reference(cardinality = ReferenceCardinality.OPTIONAL,
+            bind = "bindSadisService",
+            unbind = "unbindSadisService",
+            policy = ReferencePolicy.DYNAMIC)
+    protected volatile SadisService sadisService;
 
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected DeviceService deviceService;
@@ -124,6 +131,9 @@
     @Reference(cardinality = ReferenceCardinality.MANDATORY)
     protected ComponentConfigService componentConfigService;
 
+    @Reference(cardinality = ReferenceCardinality.MANDATORY)
+    protected StorageService storageService;
+
     /**
      * Create DHCP trap flow on NNI port(s).
      */
@@ -162,15 +172,29 @@
     protected ApplicationId appId;
     protected BaseInformationService<BandwidthProfileInformation> bpService;
     protected BaseInformationService<SubscriberAndDeviceInformation> subsService;
-    private ConcurrentMap<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingEapolForDevice
-            = new ConcurrentHashMap<>();
+    protected Map<DeviceId, BlockingQueue<SubscriberFlowInfo>> pendingEapolForDevice;
 
     @Activate
     public void activate(ComponentContext context) {
-        bpService = sadisService.getBandwidthProfileService();
-        subsService = sadisService.getSubscriberInfoService();
+        if (sadisService != null) {
+            bpService = sadisService.getBandwidthProfileService();
+            subsService = sadisService.getSubscriberInfoService();
+        } else {
+            log.warn(SADIS_NOT_RUNNING);
+        }
         componentConfigService.registerProperties(getClass());
         appId = coreService.getAppId(APP_NAME);
+        KryoNamespace serializer = KryoNamespace.newBuilder()
+                .register(KryoNamespaces.API)
+                .register(UniTagInformation.class)
+                .register(SubscriberFlowInfo.class)
+                .register(LinkedBlockingQueue.class)
+                .build();
+        pendingEapolForDevice = storageService.<DeviceId, BlockingQueue<SubscriberFlowInfo>>consistentMapBuilder()
+                .withName("volt-pending-eapol")
+                .withSerializer(Serializer.using(serializer))
+                .withApplicationId(appId)
+                .build().asJavaMap();
         log.info("started");
     }
 
@@ -228,6 +252,20 @@
 
     }
 
+    protected void bindSadisService(SadisService service) {
+        sadisService = service;
+        bpService = sadisService.getBandwidthProfileService();
+        subsService = sadisService.getSubscriberInfoService();
+        log.info("Sadis-service binds to onos.");
+    }
+
+    protected void unbindSadisService(SadisService service) {
+        sadisService = null;
+        bpService = null;
+        subsService = null;
+        log.info("Sadis-service unbinds from onos.");
+    }
+
     @Override
     public void processDhcpFilteringObjectives(DeviceId devId, PortNumber port,
                                                MeterId upstreamMeterId,
@@ -580,6 +618,7 @@
                 while (true) {
                     SubscriberFlowInfo fi = queue.remove();
                     if (fi == null) {
+                        pendingEapolForDevice.replace(devId, queue);
                         break;
                     }
                     //TODO this might return the reference and not the actual object
@@ -858,6 +897,10 @@
     }
 
     private BandwidthProfileInformation getBandwidthProfileInformation(String bandwidthProfile) {
+        if (bpService == null) {
+            log.warn(SADIS_NOT_RUNNING);
+            return null;
+        }
         if (bandwidthProfile == null) {
             return null;
         }
@@ -874,6 +917,10 @@
      * @return the default technology profile id
      */
     private int getDefaultTechProfileId(DeviceId devId, PortNumber portNumber) {
+        if (subsService == null) {
+            log.warn(SADIS_NOT_RUNNING);
+            return defaultTechProfileId;
+        }
         Port port = deviceService.getPort(devId, portNumber);
         if (port != null) {
             SubscriberAndDeviceInformation info = subsService.get(port.annotations().value(AnnotationKeys.PORT_NAME));
diff --git a/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java b/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
index d57f3c1..2acf10e 100644
--- a/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
+++ b/impl/src/main/java/org/opencord/olt/impl/OltMeterService.java
@@ -77,7 +77,6 @@
 
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
 
 /**
  * Provisions Meters on access devices.
@@ -113,9 +112,9 @@
 
     protected ExecutorService eventExecutor;
 
-    private Map<DeviceId, Set<BandwidthProfileInformation>> pendingMeters;
-    private Map<DeviceId, Map<MeterKey, AtomicInteger>> pendingRemoveMeters;
-    ConsistentMultimap<String, MeterKey> bpInfoToMeter;
+    protected Map<DeviceId, Set<BandwidthProfileInformation>> pendingMeters;
+    protected Map<DeviceId, Map<MeterKey, AtomicInteger>> pendingRemoveMeters;
+    protected ConsistentMultimap<String, MeterKey> bpInfoToMeter;
 
     @Activate
     public void activate(ComponentContext context) {
@@ -127,6 +126,7 @@
         KryoNamespace serializer = KryoNamespace.newBuilder()
                 .register(KryoNamespaces.API)
                 .register(MeterKey.class)
+                .register(BandwidthProfileInformation.class)
                 .build();
 
         bpInfoToMeter = storageService.<String, MeterKey>consistentMultimapBuilder()
@@ -137,8 +137,16 @@
 
         meterService.addListener(meterListener);
         componentConfigService.registerProperties(getClass());
-        pendingMeters = Maps.newConcurrentMap();
-        pendingRemoveMeters = Maps.newConcurrentMap();
+        pendingMeters = storageService.<DeviceId, Set<BandwidthProfileInformation>>consistentMapBuilder()
+                .withName("volt-pending-meters")
+                .withSerializer(Serializer.using(serializer))
+                .withApplicationId(appId)
+                .build().asJavaMap();
+        pendingRemoveMeters = storageService.<DeviceId, Map<MeterKey, AtomicInteger>>consistentMapBuilder()
+                .withName("volt-pending-remove-meters")
+                .withSerializer(Serializer.using(serializer))
+                .withApplicationId(appId)
+                .build().asJavaMap();
         log.info("Olt Meter service started");
     }
 
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java b/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java
index 3283886..7defeb9 100644
--- a/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java
+++ b/impl/src/test/java/org/opencord/olt/impl/OltFlowTest.java
@@ -23,6 +23,7 @@
 import java.util.Set;
 import java.util.concurrent.CompletableFuture;
 
+import com.google.common.collect.Maps;
 import org.apache.commons.lang3.tuple.Pair;
 import org.junit.Before;
 import org.junit.Test;
@@ -116,6 +117,7 @@
         oltFlowService.sadisService = new MockSadisService();
         oltFlowService.bpService = oltFlowService.sadisService.getBandwidthProfileService();
         oltFlowService.appId = appId;
+        oltFlowService.pendingEapolForDevice = Maps.newConcurrentMap();
     }
 
     @Test
@@ -123,56 +125,56 @@
         oltFlowService.flowObjectiveService.clearQueue();
         // ensure upstream dhcp traps can be added and removed
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfo,
-                                                      true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfo,
-                                                      false, true);
+                usMeterId, uniTagInfo,
+                false, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
 
         // Ensure upstream flow has no pcp unless properly specified.
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber2,
-                                                      usMeterId, uniTagInfoNoPcp,
-                                                      true, true);
+                usMeterId, uniTagInfoNoPcp,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
 
         // ensure upstream flows are not added if uniTagInfo is missing dhcp requirement
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfoNoDhcpNoIgmp,
-                                                      true, true);
+                usMeterId, uniTagInfoNoDhcpNoIgmp,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
 
         // ensure downstream traps don't succeed without global config for nni ports
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      true, false);
+                null, null,
+                true, false);
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      false, false);
+                null, null,
+                false, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
         // do global config for nni ports and now it should succeed
         oltFlowService.enableDhcpOnNni = true;
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      true, false);
+                null, null,
+                true, false);
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      false, false);
+                null, null,
+                false, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 5;
 
         // turn on DHCPv6 and we should get 2 flows
         oltFlowService.enableDhcpV6 = true;
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfo,
-                                                      true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 7;
 
         // turn off DHCPv4 and it's only v6
         oltFlowService.enableDhcpV4 = false;
         oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfo,
-                                                      true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 8;
 
         // cleanup
@@ -188,29 +190,29 @@
         // ensure pppoed traps are not added if global config is off.
         oltFlowService.enablePppoe = false;
         oltFlowService.processPPPoEDFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                        usMeterId, uniTagInfo,
-                                                        true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 0;
 
         // ensure upstream pppoed traps can be added and removed
         oltFlowService.enablePppoe = true;
         oltFlowService.processPPPoEDFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                        usMeterId, uniTagInfo,
-                                                        true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
         oltFlowService.processPPPoEDFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                        usMeterId, uniTagInfo,
-                                                        false, true);
+                usMeterId, uniTagInfo,
+                false, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
 
         // ensure downstream pppoed traps can be added and removed
         oltFlowService.processPPPoEDFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                        null, null,
-                                                        true, false);
+                null, null,
+                true, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
         oltFlowService.processPPPoEDFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                        null, null,
-                                                        false, false);
+                null, null,
+                false, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 4;
 
         // cleanup
@@ -223,31 +225,31 @@
 
         // ensure igmp flows can be added and removed
         oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfo,
-                                                      true, true);
+                usMeterId, uniTagInfo,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 1;
         oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId,
-                                                      uniTagInfo,
-                                                      false, true);
+                uniTagInfo,
+                false, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
 
         // ensure igmp flow is not added if uniTag has no igmp requirement
         oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber,
-                                                      usMeterId, uniTagInfoNoDhcpNoIgmp,
-                                                      true, true);
+                usMeterId, uniTagInfoNoDhcpNoIgmp,
+                true, true);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
 
         //ensure igmp flow on NNI fails without global setting
         oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      true, false);
+                null, null,
+                true, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 2;
 
         // igmp trap on NNI should succeed with global config
         oltFlowService.enableIgmpOnNni = true;
         oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, nniPortNumber,
-                                                      null, null,
-                                                      true, false);
+                null, null,
+                true, false);
         assert oltFlowService.flowObjectiveService.getPendingFlowObjectives().size() == 3;
         // cleanup
         oltFlowService.flowObjectiveService.clearQueue();
@@ -331,7 +333,7 @@
         assert selector.getCriterion(Criterion.Type.VLAN_VID) != null;
 
         if (!upstream) {
-            assert  selector.getCriterion(Criterion.Type.METADATA) != null;
+            assert selector.getCriterion(Criterion.Type.METADATA) != null;
         }
     }
 
diff --git a/impl/src/test/java/org/opencord/olt/impl/OltTest.java b/impl/src/test/java/org/opencord/olt/impl/OltTest.java
index c417590..af63004 100644
--- a/impl/src/test/java/org/opencord/olt/impl/OltTest.java
+++ b/impl/src/test/java/org/opencord/olt/impl/OltTest.java
@@ -18,6 +18,8 @@
 import static org.junit.Assert.assertEquals;
 
 import java.util.Set;
+
+import com.google.common.collect.Maps;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -53,6 +55,7 @@
         olt.deviceService = new MockDeviceService();
         olt.sadisService = new MockSadisService();
         olt.subsService = olt.sadisService.getSubscriberInfoService();
+        olt.pendingSubscribersForDevice = Maps.newConcurrentMap();
     }
 
     /**
@@ -75,7 +78,7 @@
     public void testGetSubscriber() {
         ConnectPoint cp = ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 2);
 
-        SubscriberAndDeviceInformation s =  olt.getSubscriber(cp);
+        SubscriberAndDeviceInformation s = olt.getSubscriber(cp);
 
         assertEquals(s.circuitId(), CLIENT_CIRCUIT_ID);
         assertEquals(s.nasPortId(), CLIENT_NAS_PORT_ID);
@@ -114,28 +117,33 @@
         }
     }
 
-    private class  MockPort implements Port {
+    private class MockPort implements Port {
 
         @Override
         public boolean isEnabled() {
             return true;
         }
+
         @Override
         public long portSpeed() {
             return 1000;
         }
+
         @Override
         public Element element() {
             return null;
         }
+
         @Override
         public PortNumber number() {
             return null;
         }
+
         @Override
         public Annotations annotations() {
             return new MockAnnotations();
         }
+
         @Override
         public Type type() {
             return Port.Type.FIBER;
@@ -147,6 +155,7 @@
             public String value(String val) {
                 return "BRCM12345678";
             }
+
             @Override
             public Set<String> keys() {
                 return null;
@@ -155,7 +164,4 @@
     }
 
 
-
-
-
 }
\ No newline at end of file
diff --git a/impl/src/test/java/org/opencord/olt/impl/TestBase.java b/impl/src/test/java/org/opencord/olt/impl/TestBase.java
index 4d7bcd5..b6546d0 100644
--- a/impl/src/test/java/org/opencord/olt/impl/TestBase.java
+++ b/impl/src/test/java/org/opencord/olt/impl/TestBase.java
@@ -82,6 +82,11 @@
 
     private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {
         @Override
+        public void clearLocalData() {
+
+        }
+
+        @Override
         public void invalidateAll() {
 
         }
@@ -113,6 +118,11 @@
         }
 
         @Override
+        public void clearLocalData() {
+
+        }
+
+        @Override
         public void invalidateAll() {
         }
 
diff --git a/pom.xml b/pom.xml
index e7e689c..79e2ecf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -31,13 +31,14 @@
     <packaging>pom</packaging>
 
     <properties>
-        <sadis.api.version>5.2.0</sadis.api.version>
+        <sadis.api.version>5.3.0-SNAPSHOT</sadis.api.version>
+        <olt.api.version>4.4.0-SNAPSHOT</olt.api.version>
     </properties>
 
     <modules>
         <module>api</module>
-        <module>web</module>
         <module>impl</module>
+        <module>web</module>
         <module>app</module>
     </modules>
 
diff --git a/web/pom.xml b/web/pom.xml
index fdbb820..aa4c814 100644
--- a/web/pom.xml
+++ b/web/pom.xml
@@ -37,7 +37,6 @@
             APIs for interacting with the CORD OLT application.
         </api.description>
         <api.package>org.opencord.olt.rest</api.package>
-        <olt.api.version>${project.version}</olt.api.version>
     </properties>
 
     <dependencies>
@@ -51,7 +50,7 @@
         <dependency>
             <groupId>org.opencord</groupId>
             <artifactId>olt-impl</artifactId>
-            <version>${olt.api.version}</version>
+            <version>${project.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -101,7 +100,6 @@
             <artifactId>javax.ws.rs-api</artifactId>
             <scope>provided</scope>
         </dependency>
-
     </dependencies>
 
     <build>