IntentStores: clear transient states, after transitioning to parking state

Fix for ONOS-372

Change-Id: I2e397f7f9a60855945fd49a8170c41ab0166f6d3
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
index 3a39193..45b4b69 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/DistributedIntentStore.java
@@ -53,6 +53,7 @@
 
 import java.util.ArrayList;
 import java.util.EnumSet;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -76,6 +77,8 @@
     /** Valid parking state, which can transition to WITHDRAWN. */
     private static final Set<IntentState> PRE_WITHDRAWN = EnumSet.of(INSTALLED, FAILED);
 
+    private static final Set<IntentState> PARKING = EnumSet.of(SUBMITTED, INSTALLED, WITHDRAWN, FAILED);
+
     private final Logger log = getLogger(getClass());
 
     // Assumption: IntentId will not have synonyms
@@ -415,6 +418,8 @@
         List<Operation> failed = new ArrayList<>();
         final Builder builder = BatchWriteRequest.newBuilder();
 
+        final Set<IntentId> transitionedToParking = new HashSet<>();
+
         for (Operation op : batch.operations()) {
             switch (op.type()) {
             case CREATE_INTENT:
@@ -440,6 +445,11 @@
                 intent = op.arg(0);
                 IntentState newState = op.arg(1);
                 builder.put(STATES_TABLE, strIntentId(intent.id()), serializer.encode(newState));
+                if (PARKING.contains(newState)) {
+                    transitionedToParking.add(intent.id());
+                } else {
+                    transitionedToParking.remove(intent.id());
+                }
                 break;
 
             case SET_INSTALLABLE:
@@ -467,6 +477,7 @@
         BatchWriteResult batchWriteResult = dbService.batchWrite(builder.build());
         if (batchWriteResult.isSuccessful()) {
             // no-failure (except for invalid input)
+            transitionedToParking.forEach((intentId) -> transientStates.remove(intentId));
             return failed;
         } else {
             // everything failed
diff --git a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
index c458446..02f7b82 100644
--- a/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
+++ b/core/store/dist/src/main/java/org/onlab/onos/store/intent/impl/HazelcastIntentStore.java
@@ -76,6 +76,8 @@
     /** Valid parking state, which can transition to WITHDRAWN. */
     private static final Set<IntentState> PRE_WITHDRAWN = EnumSet.of(INSTALLED, FAILED);
 
+    private static final Set<IntentState> PARKING = EnumSet.of(SUBMITTED, INSTALLED, WITHDRAWN, FAILED);
+
     private final Logger log = getLogger(getClass());
 
     // Assumption: IntentId will not have synonyms
@@ -348,6 +350,8 @@
         }
     }
 
+    // TODO slice out methods after merging Ali's patch
+    // CHECKSTYLE IGNORE MethodLength FOR NEXT 1 LINES
     @Override
     public List<Operation> batchWrite(BatchWrite batch) {
         // Hazelcast version will never fail for conditional failure now.
@@ -479,6 +483,10 @@
 
                 try {
                     IntentState prevIntentState = (IntentState) subops.get(0).get();
+
+                    if (PARKING.contains(newState)) {
+                        transientStates.remove(intentId);
+                    }
                     log.trace("{} - {} -> {}", intentId, prevIntentState, newState);
                     // TODO sanity check and log?
                 } catch (InterruptedException e) {