Fix bugs for dynamic interface configuration

- portNextObjStore is not updated when adding or removing portNextObjective
- Group keys for L2IG in flowObjectiveStore are deleted while modifying L2IG, which in turn causes an exception
- L3UG pointing to L2IG, which is already removed, is not removed
- Empty L2FG, with VLAN ID removed from the configuration, is not removed
- Bridging and unicast routing rules for hosts are not updated when changing port VLAN from untagged to tagged and vice versa

Change-Id: I9454fe553ae53e0fc8839a4ad629c0b5b9039a36
diff --git a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
index 281a3c1..a948bfd 100644
--- a/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
+++ b/app/src/main/java/org/onosproject/segmentrouting/SegmentRoutingManager.java
@@ -2149,6 +2149,11 @@
         if (getVlanNextObjectiveId(deviceId, vlanId) != -1) {
             // Update L2IG bucket of the port
             grpHandler.updateL2InterfaceGroupBucket(portNum, vlanId, pushVlan);
+            // Update bridging and unicast routing rule for each host
+            hostEventExecutor.execute(() -> hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum,
+                    vlanId, !pushVlan, false));
+            hostEventExecutor.execute(() -> hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum,
+                    vlanId, pushVlan, true));
         } else {
             log.warn("Failed to retrieve next objective for vlan {} in device {}:{}", vlanId, deviceId, portNum);
         }
@@ -2171,9 +2176,6 @@
         int nextId = getVlanNextObjectiveId(deviceId, vlanId);
 
         if (nextId != -1 && !install) {
-            // Update next objective for a single port as an output port
-            // Remove a single port from L2FG
-            grpHandler.updateGroupFromVlanConfiguration(vlanId, portNum, nextId, install);
             // Remove L2 Bridging rule and L3 Unicast rule to the host
             hostEventExecutor.execute(() -> hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum,
                     vlanId, pushVlan, install));
@@ -2185,10 +2187,17 @@
                 // Remove L2FG for VLAN
                 grpHandler.removeBcastGroupFromVlan(deviceId, portNum, vlanId, pushVlan);
             } else {
-                // Remove L2IG of the port
-                grpHandler.removePortNextObjective(deviceId, portNum, vlanId, pushVlan);
+                // Remove a single port from L2FG
+                grpHandler.updateGroupFromVlanConfiguration(vlanId, portNum, nextId, install);
             }
+            // Remove L2IG of the port
+            grpHandler.removePortNextObjective(deviceId, portNum, vlanId, pushVlan);
         } else if (install) {
+            // Create L2IG of the port
+            grpHandler.createPortNextObjective(deviceId, portNum, vlanId, pushVlan);
+            // Create L2 Bridging rule and L3 Unicast rule to the host
+            hostEventExecutor.execute(() -> hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum,
+                    vlanId, pushVlan, install));
             if (nextId != -1) {
                 // Add a single port to L2FG
                 grpHandler.updateGroupFromVlanConfiguration(vlanId, portNum, nextId, install);
@@ -2197,8 +2206,6 @@
                 grpHandler.createBcastGroupFromVlan(vlanId, Collections.singleton(portNum));
                 routingRulePopulator.updateSubnetBroadcastRule(deviceId, vlanId, install);
             }
-            hostEventExecutor.execute(() -> hostHandler.processIntfVlanUpdatedEvent(deviceId, portNum,
-                    vlanId, pushVlan, install));
         } else {
             log.warn("Failed to retrieve next objective for vlan {} in device {}:{}", vlanId, deviceId, portNum);
         }