Cleanup FPC agent rules on create session
diff --git a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/protocols/DpnP4Communicator.java b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/protocols/DpnP4Communicator.java
index 11c2c06..71c993e 100644
--- a/apps/fpcagent/src/main/java/org/onosproject/fpcagent/protocols/DpnP4Communicator.java
+++ b/apps/fpcagent/src/main/java/org/onosproject/fpcagent/protocols/DpnP4Communicator.java
@@ -90,11 +90,11 @@
             .withId(PiActionId.of("NoAction"))
             .build();
 
-    private static final ConcurrentMap<Long, Ip4Address> SESS_ID_TO_UE_ADDR =
+    private static final ConcurrentMap<Long, Ip4Address> UE_ADDRESSES =
             Maps.newConcurrentMap();
-    private static final ConcurrentMap<Long, Set<FlowRule>> SESS_ID_TO_FLOWS =
+    private static final ConcurrentMap<Long, Set<FlowRule>> FLOWS =
             Maps.newConcurrentMap();
-    private static final ConcurrentMap<Long, Set<Route>> SESS_ID_TO_ROUTES =
+    private static final ConcurrentMap<Long, Set<Route>> ROUTES =
             Maps.newConcurrentMap();
 
     // FIXME: should use a cache with timeout
@@ -169,20 +169,18 @@
         SESS_LOCKS.putIfAbsent(sessionId, new ReentrantLock());
         SESS_LOCKS.get(sessionId).lock();
         try {
-            if (SESS_ID_TO_FLOWS.containsKey(sessionId)
-                    && !SESS_ID_TO_FLOWS.get(sessionId).isEmpty()) {
-                log.error("Creating session {}, but {} rules already exists for such session.",
-                          sessionId, SESS_ID_TO_FLOWS.get(sessionId).size());
-                SESS_ID_TO_FLOWS.get(sessionId).forEach(f -> log.debug("{}", f));
+            if (sessionHasState(sessionId)) {
+                log.warn("Creating session {}, but state for this session is already present. Forcing cleanup of old state...");
+                logSessionState(sessionId);
+                cleanUpSession(sessionId);
             }
 
-            // If old session is there, we keep the old rules.
-            SESS_ID_TO_FLOWS.putIfAbsent(sessionId, Sets.newHashSet());
-            SESS_ID_TO_UE_ADDR.put(sessionId, ueIpv4);
+            FLOWS.putIfAbsent(sessionId, Sets.newHashSet());
+            UE_ADDRESSES.put(sessionId, ueIpv4);
 
-            SESS_ID_TO_FLOWS.get(sessionId).add(ueFilterRule(ueIpv4));
+            FLOWS.get(sessionId).add(ueFilterRule(ueIpv4));
 
-            applySessionRules(sessionId);
+            applySession(sessionId);
 
             sendNotification(
                     clientId.toString(),
@@ -211,28 +209,21 @@
         SESS_LOCKS.putIfAbsent(sessionId, new ReentrantLock());
         SESS_LOCKS.get(sessionId).lock();
         try {
-            if (!SESS_ID_TO_UE_ADDR.containsKey(sessionId)) {
+            if (!UE_ADDRESSES.containsKey(sessionId)) {
                 log.error("Missing sess ID in SESS_ID_TO_UE_ADDR map: {}",
                           sessionId);
                 return;
             }
-            final Ip4Address ueAddr = SESS_ID_TO_UE_ADDR.get(sessionId);
+            final Ip4Address ueAddr = UE_ADDRESSES.get(sessionId);
 
-            if (SESS_ID_TO_ROUTES.containsKey(sessionId)
-                    && !SESS_ID_TO_ROUTES.get(sessionId).isEmpty()) {
-                log.error("Modifying session {}, but {} DL routes already exists for such session.",
-                          sessionId, SESS_ID_TO_ROUTES.get(sessionId).size());
-                SESS_ID_TO_ROUTES.get(sessionId).forEach(r -> log.debug("{}", r));
-            }
-            SESS_ID_TO_ROUTES.putIfAbsent(sessionId, Sets.newHashSet());
-
-            SESS_ID_TO_FLOWS.get(sessionId).add(s1uFilterRule(s1USgwIpv4));
-            SESS_ID_TO_FLOWS.get(sessionId)
+            FLOWS.get(sessionId).add(s1uFilterRule(s1USgwIpv4));
+            FLOWS.get(sessionId)
                     .add(dlSessLookupRule(ueAddr, s1UEnodebTeid,
                                           s1UEnodebIpv4, s1USgwIpv4));
 
             // Segment routing configuration
-            SESS_ID_TO_ROUTES.get(sessionId).add(
+            ROUTES.putIfAbsent(sessionId, Sets.newHashSet());
+            ROUTES.get(sessionId).add(
                     new Route(Route.Source.STATIC, ueAddr.toIpPrefix(), s1UEnodebIpv4));
 
 //            List<InterfaceIpAddress> ifaceIpAddrList = Lists.newArrayList();
@@ -244,7 +235,7 @@
 //                    Collections.emptySet(), VlanId.NONE);
 //            interfaceService.add(intf);
 
-            applySessionRules(sessionId);
+            applySession(sessionId);
 
             sendNotification(
                     clientId.toString(),
@@ -270,11 +261,7 @@
         SESS_LOCKS.putIfAbsent(sessionId, new ReentrantLock());
         SESS_LOCKS.get(sessionId).lock();
         try {
-            removeSessionRules(sessionId);
-
-            SESS_ID_TO_UE_ADDR.remove(sessionId);
-            SESS_ID_TO_FLOWS.remove(sessionId);
-            SESS_ID_TO_ROUTES.remove(sessionId);
+            cleanUpSession(sessionId);
 
             sendNotification(
                     clientId.toString(),
@@ -378,31 +365,48 @@
                 .fromApp(appId);
     }
 
-    private void applySessionRules(long sessionId) {
-        if (SESS_ID_TO_FLOWS.containsKey(sessionId)) {
-            batchApply(SESS_ID_TO_FLOWS.get(sessionId));
+    private void applySession(long sessionId) {
+        if (FLOWS.containsKey(sessionId)) {
+            batchApplyFlowRules(FLOWS.get(sessionId));
         }
-        if (SESS_ID_TO_ROUTES.containsKey(sessionId)) {
-            SESS_ID_TO_ROUTES.get(sessionId).forEach(routeStore::updateRoute);
+        if (ROUTES.containsKey(sessionId)) {
+            ROUTES.get(sessionId).forEach(routeStore::updateRoute);
         }
     }
 
-    private void removeSessionRules(long sessionId) {
-        if (SESS_ID_TO_FLOWS.containsKey(sessionId)) {
-            batchRemove(SESS_ID_TO_FLOWS.get(sessionId));
+    private void cleanUpSession(long sessionId) {
+        if (FLOWS.containsKey(sessionId)) {
+            batchRemoveFlowRules(FLOWS.get(sessionId));
+            FLOWS.get(sessionId).clear();
         }
-        if (SESS_ID_TO_ROUTES.containsKey(sessionId)) {
-            SESS_ID_TO_ROUTES.get(sessionId).forEach(routeStore::removeRoute);
+        if (ROUTES.containsKey(sessionId)) {
+            ROUTES.get(sessionId).forEach(routeStore::removeRoute);
+            ROUTES.get(sessionId).clear();
+        }
+        UE_ADDRESSES.remove(sessionId);
+    }
+
+    private void logSessionState(long sessionId) {
+        if (FLOWS.containsKey(sessionId)) {
+            FLOWS.get(sessionId).forEach(f -> log.debug(f.toString()));
+        }
+        if (ROUTES.containsKey(sessionId)) {
+            ROUTES.get(sessionId).forEach(r -> log.debug(r.toString()));
         }
     }
 
-    private void batchApply(Collection<FlowRule> rules) {
+    private boolean sessionHasState(long sessionId) {
+        return (FLOWS.containsKey(sessionId) && !FLOWS.get(sessionId).isEmpty())
+                || (ROUTES.containsKey(sessionId) && !ROUTES.get(sessionId).isEmpty());
+    }
+
+    private void batchApplyFlowRules(Collection<FlowRule> rules) {
         final FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();
         rules.forEach(opsBuilder::add);
         flowRuleService.apply(opsBuilder.build());
     }
 
-    private void batchRemove(Collection<FlowRule> rules) {
+    private void batchRemoveFlowRules(Collection<FlowRule> rules) {
         final FlowRuleOperations.Builder opsBuilder = FlowRuleOperations.builder();
         rules.forEach(opsBuilder::remove);
         flowRuleService.apply(opsBuilder.build());