Updated SDN-IP to use the Intent framework batch-based intents.
Also, created a local cache of IPv4-to-MAC address mapping,
to avoid relatively costly hostService.getHostsByIp() calls
per added route.
Change-Id: I8abed378985708e883fd99e85c54b01f38756515
diff --git a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/IntentSynchronizer.java b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/IntentSynchronizer.java
index ac69faa..858f064 100644
--- a/apps/sdnip/src/main/java/org/onlab/onos/sdnip/IntentSynchronizer.java
+++ b/apps/sdnip/src/main/java/org/onlab/onos/sdnip/IntentSynchronizer.java
@@ -26,6 +26,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
+import org.apache.commons.lang3.tuple.Pair;
import org.onlab.onos.core.ApplicationId;
import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
import org.onlab.onos.net.flow.criteria.Criterion;
@@ -116,7 +117,7 @@
//
log.debug("SDN-IP Intent Synchronizer shutdown: " +
"withdrawing all intents...");
- IntentOperations.Builder builder = IntentOperations.builder();
+ IntentOperations.Builder builder = IntentOperations.builder(appId);
for (Intent intent : intentService.getIntents()) {
// Skip the intents from other applications
if (!intent.appId().equals(appId)) {
@@ -234,51 +235,84 @@
}
/**
- * Submits a multi-point-to-single-point intent.
+ * Updates multi-point-to-single-point route intents.
*
- * @param prefix the IPv4 matching prefix for the intent to submit
- * @param intent the intent to submit
+ * @param submitIntents the intents to submit
+ * @param withdrawPrefixes the IPv4 matching prefixes for the intents
+ * to withdraw
*/
- void submitRouteIntent(Ip4Prefix prefix,
- MultiPointToSinglePointIntent intent) {
- synchronized (this) {
- MultiPointToSinglePointIntent oldIntent =
- routeIntents.put(prefix, intent);
+ void updateRouteIntents(
+ Collection<Pair<Ip4Prefix, MultiPointToSinglePointIntent>> submitIntents,
+ Collection<Ip4Prefix> withdrawPrefixes) {
- if (isElectedLeader && isActivatedLeader) {
- if (oldIntent != null) {
- //
- // TODO: Short-term solution to explicitly withdraw
- // instead of using "replace" operation.
- //
- log.debug("SDN-IP Withdrawing old intent: {}", oldIntent);
- intentService.withdraw(oldIntent);
+ //
+ // NOTE: Semantically, we MUST withdraw existing intents before
+ // submitting new intents.
+ //
+ synchronized (this) {
+ MultiPointToSinglePointIntent intent;
+
+ log.debug("SDN-IP submitting intents = {} withdrawing = {}",
+ submitIntents.size(), withdrawPrefixes.size());
+
+ //
+ // Prepare the Intent batch operations for the intents to withdraw
+ //
+ IntentOperations.Builder withdrawBuilder =
+ IntentOperations.builder(appId);
+ for (Ip4Prefix prefix : withdrawPrefixes) {
+ intent = routeIntents.remove(prefix);
+ if (intent == null) {
+ log.debug("SDN-IP No intent in routeIntents to delete " +
+ "for prefix: {}", prefix);
+ continue;
}
- log.debug("SDN-IP Submitting intent: {}", intent);
- intentService.submit(intent);
- }
- }
- }
-
- /**
- * Withdraws a multi-point-to-single-point intent.
- *
- * @param prefix the IPv4 matching prefix for the intent to withdraw.
- */
- void withdrawRouteIntent(Ip4Prefix prefix) {
- synchronized (this) {
- MultiPointToSinglePointIntent intent =
- routeIntents.remove(prefix);
-
- if (intent == null) {
- log.debug("SDN-IP no intent in routeIntents to delete for " +
- "prefix: {}", prefix);
- return;
+ if (isElectedLeader && isActivatedLeader) {
+ log.debug("SDN-IP Withdrawing intent: {}", intent);
+ withdrawBuilder.addWithdrawOperation(intent.id());
+ }
}
+ //
+ // Prepare the Intent batch operations for the intents to submit
+ //
+ IntentOperations.Builder submitBuilder =
+ IntentOperations.builder(appId);
+ for (Pair<Ip4Prefix, MultiPointToSinglePointIntent> pair :
+ submitIntents) {
+ Ip4Prefix prefix = pair.getLeft();
+ intent = pair.getRight();
+ MultiPointToSinglePointIntent oldIntent =
+ routeIntents.put(prefix, intent);
+ if (isElectedLeader && isActivatedLeader) {
+ if (oldIntent != null) {
+ //
+ // TODO: Short-term solution to explicitly withdraw
+ // instead of using "replace" operation.
+ //
+ log.debug("SDN-IP Withdrawing old intent: {}",
+ oldIntent);
+ withdrawBuilder.addWithdrawOperation(oldIntent.id());
+ }
+ log.debug("SDN-IP Submitting intent: {}", intent);
+ submitBuilder.addSubmitOperation(intent);
+ }
+ }
+
+ //
+ // Submit the Intent operations
+ //
if (isElectedLeader && isActivatedLeader) {
- log.debug("SDN-IP Withdrawing intent: {}", intent);
- intentService.withdraw(intent);
+ IntentOperations intentOperations = withdrawBuilder.build();
+ if (!intentOperations.operations().isEmpty()) {
+ log.debug("SDN-IP Withdrawing intents executed");
+ intentService.execute(intentOperations);
+ }
+ intentOperations = submitBuilder.build();
+ if (!intentOperations.operations().isEmpty()) {
+ log.debug("SDN-IP Submitting intents executed");
+ intentService.execute(intentOperations);
+ }
}
}
}