Init and purge rules/group table during vtap app start and stop

Change-Id: I1382cf5ba1f74ce2c4251a41a9cc956ddb0712f1
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DistributedOpenstackVtapStore.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DistributedOpenstackVtapStore.java
index c90571f..141af0b 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DistributedOpenstackVtapStore.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/DistributedOpenstackVtapStore.java
@@ -383,10 +383,14 @@
                                                  DeviceId deviceId) {
         Set<OpenstackVtapId> vtapIds = Sets.newHashSet();
         if (type.isValid(OpenstackVtap.Type.VTAP_TX)) {
-            vtapIds.addAll(vTapIdsByTxDeviceId.get(deviceId));
+            if (vTapIdsByTxDeviceId.get(deviceId) != null) {
+                vtapIds.addAll(vTapIdsByTxDeviceId.get(deviceId));
+            }
         }
         if (type.isValid(OpenstackVtap.Type.VTAP_RX)) {
-            vtapIds.addAll(vTapIdsByRxDeviceId.get(deviceId));
+            if (vTapIdsByRxDeviceId.get(deviceId) != null) {
+                vtapIds.addAll(vTapIdsByRxDeviceId.get(deviceId));
+            }
         }
 
         return ImmutableSet.copyOf(
diff --git a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
index 843a602..dfa13ee 100644
--- a/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
+++ b/apps/openstackvtap/app/src/main/java/org/onosproject/openstackvtap/impl/OpenstackVtapManager.java
@@ -204,14 +204,15 @@
         hostService.addListener(hostListener);
         osNodeService.addListener(osNodeListener);
 
-        // TODO: need to sweep through device store and add flow rules and
-        // group tables to mirror VM traffic
+        initFlowAndGroupForCompNodes();
 
         log.info("Started {} - {}", appId.name(), this.getClass().getSimpleName());
     }
 
     @Deactivate
     public void deactivate() {
+        clearFlowAndGroupForCompNodes();
+
         osNodeService.removeListener(osNodeListener);
         hostService.removeListener(hostListener);
         deviceService.removeListener(deviceListener);
@@ -222,8 +223,6 @@
         eventExecutor.shutdown();
         leadershipService.withdraw(appId.name());
 
-        // TODO: need to purge vtap related flow rules and group tables
-
         log.info("Stopped {} - {}", appId.name(), this.getClass().getSimpleName());
     }
 
@@ -422,6 +421,14 @@
     }
 
     /**
+     * Initializes the flow rules and group tables for all completed compute nodes.
+     */
+    private void initFlowAndGroupForCompNodes() {
+        osNodeService.completeNodes(COMPUTE).forEach(node ->
+                                initFlowAndGroupByDeviceId(node.intgBridge()));
+    }
+
+    /**
      * Initializes the flow rules and group table of the given device identifier.
      *
      * @param deviceId device identifier
@@ -475,11 +482,19 @@
     }
 
     /**
+     * Purges all flow rules and group tables for completed compute nodes.
+     */
+    private void clearFlowAndGroupForCompNodes() {
+        osNodeService.completeNodes(COMPUTE).forEach(node ->
+                clearFlowAndGroupByDeviceId(node.intgBridge()));
+    }
+
+    /**
      * Purges all flow rules and group tables using the given device identifier.
      *
      * @param deviceId  device identifier
      */
-    private void clearRulesGroupTable(DeviceId deviceId) {
+    private void clearFlowAndGroupByDeviceId(DeviceId deviceId) {
         Set<FlowRule> purgedRules = Sets.newConcurrentHashSet();
         for (FlowRule flowRule : flowRuleService.getFlowRulesById(appId)) {
             if (flowRule.deviceId().equals(deviceId)) {
@@ -754,7 +769,7 @@
                     eventExecutor.execute(() -> initFlowAndGroupByDeviceId(deviceId));
                     break;
                 case OPENSTACK_NODE_REMOVED:
-                    eventExecutor.execute(() -> clearRulesGroupTable(deviceId));
+                    eventExecutor.execute(() -> clearFlowAndGroupByDeviceId(deviceId));
                 default:
                     break;
             }