Fix the rerouting problem of the shortest path intent.
- Do the execution of intents once again after the completion of executing operations
if the topology events were captured during the execution. (ONOS-1322)
Change-Id: Ie617f9303bae08a9923a23a2d4ff48cf3b751da1
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
index 5dc232e..fe8d012 100644
--- a/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PathCalcRuntimeModule.java
@@ -10,6 +10,7 @@
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.locks.ReentrantLock;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
@@ -90,12 +91,14 @@
private IEventChannel<Long, IntentOperationList> opEventChannel;
private final ReentrantLock lock = new ReentrantLock(true);
- private HashSet<LinkEvent> unmatchedLinkEvents = new HashSet<>();
- private Map<String, Set<Long>> intentInstalledMap = new ConcurrentHashMap<String, Set<Long>>();
private static final String INTENT_OP_EVENT_CHANNEL_NAME = "onos.pathintent";
private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
private static final Logger log = LoggerFactory.getLogger(PathCalcRuntimeModule.class);
+ private HashSet<LinkEvent> unmatchedLinkEvents = new HashSet<>();
+ private ConcurrentMap<String, Set<Long>> intentInstalledMap = new ConcurrentHashMap<String, Set<Long>>();
+ private ConcurrentMap<String, Intent> staleIntents = new ConcurrentHashMap<String, Intent>();
+
// ================================================================================
// private methods
// ================================================================================
@@ -111,9 +114,19 @@
if (pathIntent.isPathFrozen()) {
continue;
}
- if (pathIntent.getState().equals(IntentState.INST_ACK) && // XXX: path intents in flight
- !reroutingOperation.contains(pathIntent.getParentIntent())) {
- reroutingOperation.add(Operator.ADD, pathIntent.getParentIntent());
+ Intent parentIntent = pathIntent.getParentIntent();
+ if (parentIntent == null) {
+ continue;
+ }
+ if (pathIntent.getState().equals(IntentState.INST_ACK)) {
+ if (!reroutingOperation.contains(parentIntent)) {
+ // reroute now
+ reroutingOperation.add(Operator.ADD, parentIntent);
+ }
+ } else if (pathIntent.getState().equals(IntentState.INST_REQ)) {
+ // reroute after the completion of the current execution
+ staleIntents.put(parentIntent.getId(), parentIntent);
+ log.debug("pending reroute execution for intent ID:{}", parentIntent.getId());
}
}
executeIntentOperations(reroutingOperation);
@@ -359,6 +372,7 @@
public void entryUpdated(IntentStateList value) {
// TODO draw state transition diagram in multiple ONOS instances and update this method
+ IntentOperationList opList = new IntentOperationList();
lock.lock(); // TODO optimize locking using smaller steps
try {
log.trace("lock entryUpdated, lock obj is already locked? {}", lock.isLocked());
@@ -380,6 +394,19 @@
}
boolean isChildIntent = ((ShortestPathIntent) parentIntent).getPathIntentId().equals(pathIntentId);
+
+ // Check necessity for retrying the intent execution.
+ // When the PathIntent(=isChildIntent) transitioned to INST_{ACK/NACK}
+ // but was marked as stale (e.g., has been requested to reroute by Topology event),
+ // then immediately enqueue the re-computation of parent intent.
+ if (isChildIntent && staleIntents.containsKey(parentIntent.getId()) && (
+ nextPathIntentState.equals(IntentState.INST_ACK) ||
+ nextPathIntentState.equals(IntentState.INST_NACK))) {
+ opList.add(Operator.ADD, parentIntent);
+ staleIntents.remove(parentIntent.getId());
+ log.debug("retrying intent execution for intent ID:{}", parentIntent.getId());
+ }
+
switch (nextPathIntentState) {
case INST_ACK:
Set<Long> installedDpids = calcInstalledDpids(pathIntent, value.domainSwitchDpids);
@@ -426,6 +453,7 @@
lock.unlock();
log.trace("unlock entryUpdated");
}
+ executeIntentOperations(opList);
}
/***