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;