FlowEntry must not be modified outside store.
- Remove set method from FlowEntry
- Storing last seen timestamp for FlowEntry eviction locally on FlowManager.
FlowEntry eviction based on packet counter will take longer time to timeout
after master Node change.
Change-Id: I7134d698dd5b9bf7cca379c5ba7c4fbcc2e3d5f3
diff --git a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
index b6ebda4..8ca2ca0 100644
--- a/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
+++ b/core/store/trivial/src/main/java/org/onlab/onos/store/trivial/impl/SimpleFlowRuleStore.java
@@ -5,6 +5,7 @@
import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked;
import static java.util.Collections.unmodifiableCollection;
+import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -25,6 +26,7 @@
import org.onlab.onos.net.flow.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
+import org.onlab.onos.net.flow.StoredFlowEntry;
import org.onlab.onos.store.AbstractStore;
import org.onlab.util.NewConcurrentHashMap;
import org.slf4j.Logger;
@@ -43,7 +45,7 @@
// inner Map is Device flow table
// Assumption: FlowId cannot have synonyms
- private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, FlowEntry>>
+ private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, StoredFlowEntry>>
flowEntries = new ConcurrentHashMap<>();
@Activate
@@ -61,14 +63,14 @@
@Override
public int getFlowRuleCount() {
int sum = 0;
- for (ConcurrentMap<FlowId, FlowEntry> ft : flowEntries.values()) {
+ for (ConcurrentMap<FlowId, StoredFlowEntry> ft : flowEntries.values()) {
sum += ft.size();
}
return sum;
}
- private static NewConcurrentHashMap<FlowId, FlowEntry> lazyEmptyFlowTable() {
- return NewConcurrentHashMap.<FlowId, FlowEntry>ifNeeded();
+ private static NewConcurrentHashMap<FlowId, StoredFlowEntry> lazyEmptyFlowTable() {
+ return NewConcurrentHashMap.<FlowId, StoredFlowEntry>ifNeeded();
}
/**
@@ -77,12 +79,12 @@
* @param deviceId identifier of the device
* @return Map representing Flow Table of given device.
*/
- private ConcurrentMap<FlowId, FlowEntry> getFlowTable(DeviceId deviceId) {
+ private ConcurrentMap<FlowId, StoredFlowEntry> getFlowTable(DeviceId deviceId) {
return createIfAbsentUnchecked(flowEntries,
deviceId, lazyEmptyFlowTable());
}
- private FlowEntry getFlowEntry(DeviceId deviceId, FlowId flowId) {
+ private StoredFlowEntry getFlowEntry(DeviceId deviceId, FlowId flowId) {
return getFlowTable(deviceId).get(flowId);
}
@@ -93,7 +95,8 @@
@Override
public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
- return unmodifiableCollection(getFlowTable(deviceId).values());
+ return unmodifiableCollection((Collection<? extends FlowEntry>)
+ getFlowTable(deviceId).values());
}
@Override
@@ -101,7 +104,7 @@
Set<FlowRule> rules = new HashSet<>();
for (DeviceId did : flowEntries.keySet()) {
- ConcurrentMap<FlowId, FlowEntry> ft = getFlowTable(did);
+ ConcurrentMap<FlowId, StoredFlowEntry> ft = getFlowTable(did);
for (FlowEntry fe : ft.values()) {
if (fe.appId() == appId.id()) {
rules.add(fe);
@@ -117,7 +120,7 @@
}
private boolean storeFlowRuleInternal(FlowRule rule) {
- FlowEntry f = new DefaultFlowEntry(rule);
+ StoredFlowEntry f = new DefaultFlowEntry(rule);
final DeviceId did = f.deviceId();
final FlowId fid = f.id();
FlowEntry existing = getFlowTable(did).putIfAbsent(fid, f);
@@ -133,7 +136,7 @@
@Override
public void deleteFlowRule(FlowRule rule) {
- FlowEntry entry = getFlowEntry(rule.deviceId(), rule.id());
+ StoredFlowEntry entry = getFlowEntry(rule.deviceId(), rule.id());
if (entry == null) {
//log.warn("Cannot find rule {}", rule);
return;
@@ -146,7 +149,7 @@
@Override
public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
// check if this new rule is an update to an existing entry
- FlowEntry stored = getFlowEntry(rule.deviceId(), rule.id());
+ StoredFlowEntry stored = getFlowEntry(rule.deviceId(), rule.id());
if (stored != null) {
synchronized (stored) {
stored.setBytes(rule.bytes());
@@ -174,7 +177,7 @@
// This is where one could mark a rule as removed and still keep it in the store.
final DeviceId did = rule.deviceId();
- ConcurrentMap<FlowId, FlowEntry> ft = getFlowTable(did);
+ ConcurrentMap<FlowId, StoredFlowEntry> ft = getFlowTable(did);
if (ft.remove(rule.id(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {