resilient flows and application id
Change-Id: Ic9f192d4451ae962737ab2b45c644372535e7bdb
diff --git a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
index b3481c1..238c4d0 100644
--- a/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
+++ b/core/net/src/main/java/org/onlab/onos/net/flow/impl/FlowRuleManager.java
@@ -12,14 +12,13 @@
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
+import org.onlab.onos.ApplicationId;
import org.onlab.onos.event.AbstractListenerRegistry;
import org.onlab.onos.event.EventDeliveryService;
import org.onlab.onos.net.Device;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.device.DeviceService;
-import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.FlowRule;
-import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleListener;
import org.onlab.onos.net.flow.FlowRuleProvider;
@@ -77,7 +76,7 @@
@Override
public void applyFlowRules(FlowRule... flowRules) {
for (int i = 0; i < flowRules.length; i++) {
- FlowRule f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_ADD);
+ FlowRule f = flowRules[i];
final Device device = deviceService.getDevice(f.deviceId());
final FlowRuleProvider frp = getProvider(device.providerId());
store.storeFlowRule(f);
@@ -88,14 +87,33 @@
@Override
public void removeFlowRules(FlowRule... flowRules) {
FlowRule f;
+ FlowRuleProvider frp;
+ Device device;
for (int i = 0; i < flowRules.length; i++) {
- f = new DefaultFlowRule(flowRules[i], FlowRuleState.PENDING_REMOVE);
- final Device device = deviceService.getDevice(f.deviceId());
- final FlowRuleProvider frp = getProvider(device.providerId());
+ f = flowRules[i];
+ device = deviceService.getDevice(f.deviceId());
+ frp = getProvider(device.providerId());
store.deleteFlowRule(f);
frp.removeFlowRule(f);
}
+ }
+ @Override
+ public void removeFlowRulesById(ApplicationId id) {
+ Iterable<FlowRule> rules = getFlowRulesById(id);
+ FlowRuleProvider frp;
+ Device device;
+ for (FlowRule f : rules) {
+ store.deleteFlowRule(f);
+ device = deviceService.getDevice(f.deviceId());
+ frp = getProvider(device.providerId());
+ frp.removeRulesById(id, f);
+ }
+ }
+
+ @Override
+ public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
+ return store.getFlowEntriesByAppId(id);
}
@Override
@@ -126,8 +144,27 @@
public void flowRemoved(FlowRule flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
checkValidity();
- FlowRuleEvent event = store.removeFlowRule(flowRule);
+ FlowRule stored = store.getFlowRule(flowRule);
+ if (stored == null) {
+ log.debug("Rule already evicted from store: {}", flowRule);
+ return;
+ }
+ Device device = deviceService.getDevice(flowRule.deviceId());
+ FlowRuleProvider frp = getProvider(device.providerId());
+ FlowRuleEvent event = null;
+ switch (stored.state()) {
+ case ADDED:
+ case PENDING_ADD:
+ frp.applyFlowRule(flowRule);
+ break;
+ case PENDING_REMOVE:
+ case REMOVED:
+ event = store.removeFlowRule(flowRule);
+ break;
+ default:
+ break;
+ }
if (event != null) {
log.debug("Flow {} removed", flowRule);
post(event);
@@ -138,7 +175,22 @@
public void flowMissing(FlowRule flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
checkValidity();
- log.debug("Flow {} has not been installed.", flowRule);
+ Device device = deviceService.getDevice(flowRule.deviceId());
+ FlowRuleProvider frp = getProvider(device.providerId());
+ switch (flowRule.state()) {
+ case PENDING_REMOVE:
+ case REMOVED:
+ store.removeFlowRule(flowRule);
+ frp.removeFlowRule(flowRule);
+ break;
+ case ADDED:
+ case PENDING_ADD:
+ frp.applyFlowRule(flowRule);
+ break;
+ default:
+ log.debug("Flow {} has not been installed.", flowRule);
+ }
+
}
@@ -146,6 +198,7 @@
public void extraneousFlow(FlowRule flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
checkValidity();
+ removeFlowRules(flowRule);
log.debug("Flow {} is on switch but not in store.", flowRule);
}
diff --git a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
index 8d82320..4e634c9 100644
--- a/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
+++ b/core/net/src/test/java/org/onlab/onos/net/flow/impl/FlowRuleManagerTest.java
@@ -14,6 +14,7 @@
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
+import org.onlab.onos.ApplicationId;
import org.onlab.onos.event.impl.TestEventDispatcher;
import org.onlab.onos.net.DefaultDevice;
import org.onlab.onos.net.Device;
@@ -61,6 +62,7 @@
protected FlowRuleProviderService providerService;
protected TestProvider provider;
protected TestListener listener = new TestListener();
+ private ApplicationId appId;
@Before
public void setUp() {
@@ -75,6 +77,7 @@
mgr.addListener(listener);
provider = new TestProvider(PID);
providerService = registry.register(provider);
+ appId = ApplicationId.getAppId();
assertTrue("provider should be registered",
registry.getProviders().contains(provider.id()));
}
@@ -93,7 +96,7 @@
private FlowRule flowRule(int tsval, int trval) {
TestSelector ts = new TestSelector(tsval);
TestTreatment tr = new TestTreatment(trval);
- return new DefaultFlowRule(DID, ts, tr, 0);
+ return new DefaultFlowRule(DID, ts, tr, 0, appId);
}
private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
@@ -159,8 +162,8 @@
public void applyFlowRules() {
FlowRule r1 = flowRule(1, 1);
- FlowRule r2 = flowRule(1, 2);
- FlowRule r3 = flowRule(1, 3);
+ FlowRule r2 = flowRule(2, 2);
+ FlowRule r3 = flowRule(3, 3);
assertTrue("store should be empty",
Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
@@ -196,6 +199,7 @@
@Test
public void flowRemoved() {
FlowRule f1 = addFlowRule(1);
+ service.removeFlowRules(f1);
addFlowRule(2);
FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
providerService.flowRemoved(rem1);
@@ -293,6 +297,11 @@
public void removeFlowRule(FlowRule... flowRules) {
}
+ @Override
+ public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
+ }
+
+
}
private class TestSelector implements TrafficSelector {