ONOS-1404 - Rerouting delayed due to flows being removed out of order
ONOS-1409 - handle all links to a switch going away and coming back
Change-Id: Ib7216530fa8eef41b1088c5122a40bf9265481ca
diff --git a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
index ddccb53..610b030 100644
--- a/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
+++ b/core/net/src/main/java/org/onosproject/net/intent/impl/IntentManager.java
@@ -15,7 +15,15 @@
*/
package org.onosproject.net.intent.impl;
-import com.google.common.collect.ImmutableList;
+import java.util.Collection;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Future;
+import java.util.stream.Collectors;
+
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
@@ -48,15 +56,7 @@
import org.onosproject.net.intent.impl.phase.IntentWorker;
import org.slf4j.Logger;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Future;
-import java.util.stream.Collectors;
+import com.google.common.collect.ImmutableList;
import static com.google.common.base.Preconditions.checkNotNull;
import static java.util.concurrent.Executors.newFixedThreadPool;
@@ -359,97 +359,92 @@
}
@Override
- public void install(IntentData data) {
- IntentManager.this.install(data);
+ public void apply(IntentData toUninstall, IntentData toInstall) {
+ IntentManager.this.apply(toUninstall, toInstall);
}
+ }
- @Override
- public void uninstall(IntentData data) {
- IntentManager.this.uninstall(data);
+ private enum Direction {
+ ADD,
+ REMOVE
+ }
+
+ private void applyIntentData(IntentData data,
+ FlowRuleOperations.Builder builder,
+ Direction direction) {
+ if (data != null) {
+ List<Intent> intentsToApply = data.installables();
+ if (!intentsToApply.stream().allMatch(x -> x instanceof FlowRuleIntent)) {
+ throw new IllegalStateException("installable intents must be FlowRuleIntent");
+ }
+
+ if (direction == Direction.ADD) {
+ trackerService.addTrackedResources(data.key(), data.intent().resources());
+ intentsToApply.forEach(installable ->
+ trackerService.addTrackedResources(data.key(), installable.resources()));
+ } else {
+ trackerService.removeTrackedResources(data.key(), data.intent().resources());
+ intentsToApply.forEach(installable ->
+ trackerService.removeTrackedResources(data.intent().key(),
+ installable.resources()));
+ }
+
+ // FIXME do FlowRuleIntents have stages??? Can we do uninstall work in parallel? I think so.
+ builder.newStage();
+
+ List<Collection<FlowRule>> stages = intentsToApply.stream()
+ .map(x -> (FlowRuleIntent) x)
+ .map(FlowRuleIntent::flowRules)
+ .collect(Collectors.toList());
+
+ for (Collection<FlowRule> rules : stages) {
+ if (direction == Direction.ADD) {
+ rules.forEach(builder::add);
+ } else {
+ rules.forEach(builder::remove);
+ }
+ }
}
}
- private void install(IntentData data) {
+ private void apply(IntentData toUninstall, IntentData toInstall) {
// need to consider if FlowRuleIntent is only one as installable intent or not
- List<Intent> installables = data.installables();
- if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) {
- throw new IllegalStateException("installable intents must be FlowRuleIntent");
- }
-
- trackerService.addTrackedResources(data.key(), data.intent().resources());
- installables.forEach(installable ->
- trackerService.addTrackedResources(data.key(), installable.resources()));
-
- List<Collection<FlowRule>> stages = installables.stream()
- .map(x -> (FlowRuleIntent) x)
- .map(FlowRuleIntent::flowRules)
- .collect(Collectors.toList());
FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
- for (Collection<FlowRule> rules : stages) {
- rules.forEach(builder::add);
- builder.newStage();
- }
+ applyIntentData(toUninstall, builder, Direction.REMOVE);
+ applyIntentData(toInstall, builder, Direction.ADD);
FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() {
@Override
public void onSuccess(FlowRuleOperations ops) {
- log.debug("Completed installing: {}", data.key());
- data.setState(INSTALLED);
- store.write(data);
+ if (toInstall != null) {
+ log.debug("Completed installing: {}", toInstall.key());
+ //FIXME state depends on install.... we might want to pass this in.
+ toInstall.setState(INSTALLED);
+ store.write(toInstall);
+ } else if (toUninstall != null) {
+ log.debug("Completed withdrawing: {}", toUninstall.key());
+ //FIXME state depends on install.... we might want to pass this in.
+ toUninstall.setState(WITHDRAWN);
+ store.write(toUninstall);
+ }
}
@Override
public void onError(FlowRuleOperations ops) {
- log.warn("Failed installation: {} {} on {}", data.key(), data.intent(), ops);
- data.setState(FAILED);
- store.write(data);
+ if (toInstall != null) {
+ log.warn("Failed installation: {} {} on {}", toInstall.key(), toInstall.intent(), ops);
+ //FIXME
+ toInstall.setState(FAILED);
+ store.write(toInstall);
+ }
+ // if toInstall was cause of error, then recompile (manage/increment counter, when exceeded -> CORRUPT)
+ // if toUninstall was cause of error, then CORRUPT (another job will lean this up)
}
});
flowRuleService.apply(operations);
}
- private void uninstall(IntentData data) {
- List<Intent> installables = data.installables();
- if (!installables.stream().allMatch(x -> x instanceof FlowRuleIntent)) {
- throw new IllegalStateException("installable intents must be FlowRuleIntent");
- }
-
- trackerService.removeTrackedResources(data.key(), data.intent().resources());
- installables.forEach(installable ->
- trackerService.removeTrackedResources(data.intent().key(),
- installable.resources()));
-
- List<Collection<FlowRule>> stages = installables.stream()
- .map(x -> (FlowRuleIntent) x)
- .map(FlowRuleIntent::flowRules)
- .collect(Collectors.toList());
-
- FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
- for (Collection<FlowRule> rules : stages) {
- rules.forEach(builder::remove);
- builder.newStage();
- }
-
- FlowRuleOperations operations = builder.build(new FlowRuleOperationsContext() {
- @Override
- public void onSuccess(FlowRuleOperations ops) {
- log.debug("Completed withdrawing: {}", data.key());
- data.setState(WITHDRAWN);
- data.setInstallables(Collections.emptyList());
- store.write(data);
- }
-
- @Override
- public void onError(FlowRuleOperations ops) {
- log.warn("Failed withdraw: {}", data.key());
- data.setState(FAILED);
- store.write(data);
- }
- });
-
- flowRuleService.apply(operations);
- }
}