DistributedIntentStore: add sanity check to parking state transition

Change-Id: I2958a5889451a4f7a34146033a801cf89b73a1cc
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 d786a6c..ae5fb4a 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
@@ -39,8 +39,10 @@
 import org.onlab.util.KryoNamespace;
 import org.slf4j.Logger;
 
+import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 
 import static com.google.common.base.Verify.verify;
@@ -53,6 +55,12 @@
         extends AbstractHazelcastStore<IntentEvent, IntentStoreDelegate>
         implements IntentStore {
 
+    /** Valid parking state, which can transition to INSTALLED. */
+    private static final Set<IntentState> PRE_INSTALLED = EnumSet.of(SUBMITTED, FAILED);
+
+    /** Valid parking state, which can transition to WITHDRAWN. */
+    private static final Set<IntentState> PRE_WITHDRAWN = EnumSet.of(INSTALLED, FAILED);
+
     private final Logger log = getLogger(getClass());
 
     // Assumption: IntentId will not have synonyms
@@ -158,45 +166,52 @@
         return states.get(id);
     }
 
+
     @Override
     public IntentEvent setState(Intent intent, IntentState state) {
         final IntentId id = intent.id();
         IntentEvent.Type type = null;
-        IntentState prev = null;
+        final IntentState prevParking;
         boolean transientStateChangeOnly = false;
 
-        // TODO: enable sanity checking if Debug enabled, etc.
+        // parking state transition
         switch (state) {
         case SUBMITTED:
-            prev = states.putIfAbsent(id, SUBMITTED);
-            verify(prev == null, "Illegal state transition attempted from %s to SUBMITTED", prev);
+            prevParking = states.putIfAbsent(id, SUBMITTED);
+            verify(prevParking == null,
+                   "Illegal state transition attempted from %s to SUBMITTED",
+                   prevParking);
             type = IntentEvent.Type.SUBMITTED;
             break;
         case INSTALLED:
-            // parking state transition
-            prev = states.replace(id, INSTALLED);
-            verify(prev != null, "Illegal state transition attempted from non-SUBMITTED to INSTALLED");
+            prevParking = states.replace(id, INSTALLED);
+            verify(PRE_INSTALLED.contains(prevParking),
+                   "Illegal state transition attempted from %s to INSTALLED",
+                   prevParking);
             type = IntentEvent.Type.INSTALLED;
             break;
         case FAILED:
-            prev = states.replace(id, FAILED);
+            prevParking = states.replace(id, FAILED);
             type = IntentEvent.Type.FAILED;
             break;
         case WITHDRAWN:
-            prev = states.replace(id, WITHDRAWN);
-            verify(prev != null, "Illegal state transition attempted from non-WITHDRAWING to WITHDRAWN");
+            prevParking = states.replace(id, WITHDRAWN);
+            verify(PRE_WITHDRAWN.contains(prevParking),
+                   "Illegal state transition attempted from %s to WITHDRAWN",
+                   prevParking);
             type = IntentEvent.Type.WITHDRAWN;
             break;
         default:
             transientStateChangeOnly = true;
+            prevParking = null;
             break;
         }
         if (!transientStateChangeOnly) {
-            log.debug("Parking State change: {} {}=>{}",  id, prev, state);
+            log.debug("Parking State change: {} {}=>{}",  id, prevParking, state);
         }
         // Update instance local state, which includes non-parking state transition
-        prev = transientStates.put(id, state);
-        log.debug("Transient State change: {} {}=>{}", id, prev, state);
+        final IntentState prevTransient = transientStates.put(id, state);
+        log.debug("Transient State change: {} {}=>{}", id, prevTransient, state);
 
         if (type == null) {
             return null;