Yuta HIGUCHI

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
...@@ -6,7 +6,8 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -6,7 +6,8 @@ import static org.slf4j.LoggerFactory.getLogger;
6 import org.onlab.onos.net.DeviceId; 6 import org.onlab.onos.net.DeviceId;
7 import org.slf4j.Logger; 7 import org.slf4j.Logger;
8 8
9 -public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry { 9 +public class DefaultFlowEntry extends DefaultFlowRule
10 + implements FlowEntry, StoredFlowEntry {
10 11
11 private static final Logger log = getLogger(DefaultFlowEntry.class); 12 private static final Logger log = getLogger(DefaultFlowEntry.class);
12 13
......
...@@ -65,6 +65,7 @@ public interface FlowEntry extends FlowRule { ...@@ -65,6 +65,7 @@ public interface FlowEntry extends FlowRule {
65 */ 65 */
66 long bytes(); 66 long bytes();
67 67
68 + // TODO: consider removing this attribute
68 /** 69 /**
69 * When this flow entry was last deemed active. 70 * When this flow entry was last deemed active.
70 * @return epoch time of last activity 71 * @return epoch time of last activity
...@@ -72,35 +73,6 @@ public interface FlowEntry extends FlowRule { ...@@ -72,35 +73,6 @@ public interface FlowEntry extends FlowRule {
72 long lastSeen(); 73 long lastSeen();
73 74
74 /** 75 /**
75 - * Sets the last active epoch time.
76 - */
77 - void setLastSeen();
78 -
79 - /**
80 - * Sets the new state for this entry.
81 - * @param newState new flow entry state.
82 - */
83 - void setState(FlowEntryState newState);
84 -
85 - /**
86 - * Sets how long this entry has been entered in the system.
87 - * @param life epoch time
88 - */
89 - void setLife(long life);
90 -
91 - /**
92 - * Number of packets seen by this entry.
93 - * @param packets a long value
94 - */
95 - void setPackets(long packets);
96 -
97 - /**
98 - * Number of bytes seen by this rule.
99 - * @param bytes a long value
100 - */
101 - void setBytes(long bytes);
102 -
103 - /**
104 * Indicates the error type. 76 * Indicates the error type.
105 * @return an integer value of the error 77 * @return an integer value of the error
106 */ 78 */
......
1 +package org.onlab.onos.net.flow;
2 +
3 +
4 +public interface StoredFlowEntry extends FlowEntry {
5 +
6 + /**
7 + * Sets the last active epoch time.
8 + */
9 + void setLastSeen();
10 +
11 + /**
12 + * Sets the new state for this entry.
13 + * @param newState new flow entry state.
14 + */
15 + void setState(FlowEntryState newState);
16 +
17 + /**
18 + * Sets how long this entry has been entered in the system.
19 + * @param life epoch time
20 + */
21 + void setLife(long life);
22 +
23 + /**
24 + * Number of packets seen by this entry.
25 + * @param packets a long value
26 + */
27 + void setPackets(long packets);
28 +
29 + /**
30 + * Number of bytes seen by this rule.
31 + * @param bytes a long value
32 + */
33 + void setBytes(long bytes);
34 +
35 +}
...@@ -3,8 +3,8 @@ package org.onlab.onos.net.flow.impl; ...@@ -3,8 +3,8 @@ package org.onlab.onos.net.flow.impl;
3 import static com.google.common.base.Preconditions.checkNotNull; 3 import static com.google.common.base.Preconditions.checkNotNull;
4 import static org.slf4j.LoggerFactory.getLogger; 4 import static org.slf4j.LoggerFactory.getLogger;
5 5
6 -import java.util.Iterator;
7 import java.util.List; 6 import java.util.List;
7 +import java.util.Map;
8 import java.util.concurrent.CancellationException; 8 import java.util.concurrent.CancellationException;
9 import java.util.concurrent.ExecutionException; 9 import java.util.concurrent.ExecutionException;
10 import java.util.concurrent.Future; 10 import java.util.concurrent.Future;
...@@ -45,6 +45,7 @@ import org.slf4j.Logger; ...@@ -45,6 +45,7 @@ import org.slf4j.Logger;
45 45
46 import com.google.common.collect.ArrayListMultimap; 46 import com.google.common.collect.ArrayListMultimap;
47 import com.google.common.collect.Lists; 47 import com.google.common.collect.Lists;
48 +import com.google.common.collect.Maps;
48 import com.google.common.collect.Multimap; 49 import com.google.common.collect.Multimap;
49 50
50 /** 51 /**
...@@ -197,6 +198,8 @@ public class FlowRuleManager ...@@ -197,6 +198,8 @@ public class FlowRuleManager
197 extends AbstractProviderService<FlowRuleProvider> 198 extends AbstractProviderService<FlowRuleProvider>
198 implements FlowRuleProviderService { 199 implements FlowRuleProviderService {
199 200
201 + final Map<FlowEntry, Long> lastSeen = Maps.newConcurrentMap();
202 +
200 protected InternalFlowRuleProviderService(FlowRuleProvider provider) { 203 protected InternalFlowRuleProviderService(FlowRuleProvider provider) {
201 super(provider); 204 super(provider);
202 } 205 }
...@@ -205,6 +208,7 @@ public class FlowRuleManager ...@@ -205,6 +208,7 @@ public class FlowRuleManager
205 public void flowRemoved(FlowEntry flowEntry) { 208 public void flowRemoved(FlowEntry flowEntry) {
206 checkNotNull(flowEntry, FLOW_RULE_NULL); 209 checkNotNull(flowEntry, FLOW_RULE_NULL);
207 checkValidity(); 210 checkValidity();
211 + lastSeen.remove(flowEntry);
208 FlowEntry stored = store.getFlowEntry(flowEntry); 212 FlowEntry stored = store.getFlowEntry(flowEntry);
209 if (stored == null) { 213 if (stored == null) {
210 log.info("Rule already evicted from store: {}", flowEntry); 214 log.info("Rule already evicted from store: {}", flowEntry);
...@@ -292,14 +296,25 @@ public class FlowRuleManager ...@@ -292,14 +296,25 @@ public class FlowRuleManager
292 if (storedRule == null) { 296 if (storedRule == null) {
293 return false; 297 return false;
294 } 298 }
295 - long timeout = storedRule.timeout() * 1000; 299 + final long timeout = storedRule.timeout() * 1000;
296 - Long currentTime = System.currentTimeMillis(); 300 + final long currentTime = System.currentTimeMillis();
297 if (storedRule.packets() != swRule.packets()) { 301 if (storedRule.packets() != swRule.packets()) {
298 - storedRule.setLastSeen(); 302 + lastSeen.put(storedRule, currentTime);
299 return true; 303 return true;
300 } 304 }
305 + if (!lastSeen.containsKey(storedRule)) {
306 + // checking for the first time
307 + lastSeen.put(storedRule, storedRule.lastSeen());
308 + // Use following if lastSeen attr. was removed.
309 + //lastSeen.put(storedRule, currentTime);
310 + }
311 + Long last = lastSeen.get(storedRule);
312 + if (last == null) {
313 + // concurrently removed? let the liveness check fail
314 + return false;
315 + }
301 316
302 - if ((currentTime - storedRule.lastSeen()) <= timeout) { 317 + if ((currentTime - last) <= timeout) {
303 return true; 318 return true;
304 } 319 }
305 return false; 320 return false;
...@@ -316,10 +331,7 @@ public class FlowRuleManager ...@@ -316,10 +331,7 @@ public class FlowRuleManager
316 public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) { 331 public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
317 List<FlowEntry> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId)); 332 List<FlowEntry> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
318 333
319 - Iterator<FlowEntry> switchRulesIterator = flowEntries.iterator(); 334 + for (FlowEntry rule : flowEntries) {
320 -
321 - while (switchRulesIterator.hasNext()) {
322 - FlowEntry rule = switchRulesIterator.next();
323 if (storedRules.remove(rule)) { 335 if (storedRules.remove(rule)) {
324 // we both have the rule, let's update some info then. 336 // we both have the rule, let's update some info then.
325 flowAdded(rule); 337 flowAdded(rule);
......
...@@ -46,6 +46,7 @@ import org.onlab.onos.net.flow.FlowRuleProvider; ...@@ -46,6 +46,7 @@ import org.onlab.onos.net.flow.FlowRuleProvider;
46 import org.onlab.onos.net.flow.FlowRuleProviderRegistry; 46 import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
47 import org.onlab.onos.net.flow.FlowRuleProviderService; 47 import org.onlab.onos.net.flow.FlowRuleProviderService;
48 import org.onlab.onos.net.flow.FlowRuleService; 48 import org.onlab.onos.net.flow.FlowRuleService;
49 +import org.onlab.onos.net.flow.StoredFlowEntry;
49 import org.onlab.onos.net.flow.TrafficSelector; 50 import org.onlab.onos.net.flow.TrafficSelector;
50 import org.onlab.onos.net.flow.TrafficTreatment; 51 import org.onlab.onos.net.flow.TrafficTreatment;
51 import org.onlab.onos.net.flow.criteria.Criterion; 52 import org.onlab.onos.net.flow.criteria.Criterion;
...@@ -232,7 +233,7 @@ public class FlowRuleManagerTest { ...@@ -232,7 +233,7 @@ public class FlowRuleManagerTest {
232 public void flowRemoved() { 233 public void flowRemoved() {
233 FlowRule f1 = addFlowRule(1); 234 FlowRule f1 = addFlowRule(1);
234 FlowRule f2 = addFlowRule(2); 235 FlowRule f2 = addFlowRule(2);
235 - FlowEntry fe1 = new DefaultFlowEntry(f1); 236 + StoredFlowEntry fe1 = new DefaultFlowEntry(f1);
236 FlowEntry fe2 = new DefaultFlowEntry(f2); 237 FlowEntry fe2 = new DefaultFlowEntry(f2);
237 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2)); 238 providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
238 service.removeFlowRules(f1); 239 service.removeFlowRules(f1);
......
...@@ -26,6 +26,7 @@ import org.onlab.onos.net.flow.FlowRuleEvent; ...@@ -26,6 +26,7 @@ import org.onlab.onos.net.flow.FlowRuleEvent;
26 import org.onlab.onos.net.flow.FlowRuleEvent.Type; 26 import org.onlab.onos.net.flow.FlowRuleEvent.Type;
27 import org.onlab.onos.net.flow.FlowRuleStore; 27 import org.onlab.onos.net.flow.FlowRuleStore;
28 import org.onlab.onos.net.flow.FlowRuleStoreDelegate; 28 import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
29 +import org.onlab.onos.net.flow.StoredFlowEntry;
29 import org.onlab.onos.store.AbstractStore; 30 import org.onlab.onos.store.AbstractStore;
30 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService; 31 import org.onlab.onos.store.cluster.messaging.ClusterCommunicationService;
31 import org.onlab.onos.store.cluster.messaging.ClusterMessage; 32 import org.onlab.onos.store.cluster.messaging.ClusterMessage;
...@@ -53,8 +54,8 @@ public class DistributedFlowRuleStore ...@@ -53,8 +54,8 @@ public class DistributedFlowRuleStore
53 private final Logger log = getLogger(getClass()); 54 private final Logger log = getLogger(getClass());
54 55
55 // store entries as a pile of rules, no info about device tables 56 // store entries as a pile of rules, no info about device tables
56 - private final Multimap<DeviceId, FlowEntry> flowEntries = 57 + private final Multimap<DeviceId, StoredFlowEntry> flowEntries =
57 - ArrayListMultimap.<DeviceId, FlowEntry>create(); 58 + ArrayListMultimap.<DeviceId, StoredFlowEntry>create();
58 59
59 private final Multimap<Short, FlowRule> flowEntriesById = 60 private final Multimap<Short, FlowRule> flowEntriesById =
60 ArrayListMultimap.<Short, FlowRule>create(); 61 ArrayListMultimap.<Short, FlowRule>create();
...@@ -99,7 +100,11 @@ public class DistributedFlowRuleStore ...@@ -99,7 +100,11 @@ public class DistributedFlowRuleStore
99 100
100 @Override 101 @Override
101 public synchronized FlowEntry getFlowEntry(FlowRule rule) { 102 public synchronized FlowEntry getFlowEntry(FlowRule rule) {
102 - for (FlowEntry f : flowEntries.get(rule.deviceId())) { 103 + return getFlowEntryInternal(rule);
104 + }
105 +
106 + private synchronized StoredFlowEntry getFlowEntryInternal(FlowRule rule) {
107 + for (StoredFlowEntry f : flowEntries.get(rule.deviceId())) {
103 if (f.equals(rule)) { 108 if (f.equals(rule)) {
104 return f; 109 return f;
105 } 110 }
...@@ -109,7 +114,7 @@ public class DistributedFlowRuleStore ...@@ -109,7 +114,7 @@ public class DistributedFlowRuleStore
109 114
110 @Override 115 @Override
111 public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { 116 public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
112 - Collection<FlowEntry> rules = flowEntries.get(deviceId); 117 + Collection<? extends FlowEntry> rules = flowEntries.get(deviceId);
113 if (rules == null) { 118 if (rules == null) {
114 return Collections.emptyList(); 119 return Collections.emptyList();
115 } 120 }
...@@ -148,7 +153,7 @@ public class DistributedFlowRuleStore ...@@ -148,7 +153,7 @@ public class DistributedFlowRuleStore
148 } 153 }
149 154
150 private synchronized void storeFlowEntryInternal(FlowRule flowRule) { 155 private synchronized void storeFlowEntryInternal(FlowRule flowRule) {
151 - FlowEntry flowEntry = new DefaultFlowEntry(flowRule); 156 + StoredFlowEntry flowEntry = new DefaultFlowEntry(flowRule);
152 DeviceId deviceId = flowRule.deviceId(); 157 DeviceId deviceId = flowRule.deviceId();
153 // write to local copy. 158 // write to local copy.
154 if (!flowEntries.containsEntry(deviceId, flowEntry)) { 159 if (!flowEntries.containsEntry(deviceId, flowEntry)) {
...@@ -182,7 +187,7 @@ public class DistributedFlowRuleStore ...@@ -182,7 +187,7 @@ public class DistributedFlowRuleStore
182 } 187 }
183 188
184 private synchronized void deleteFlowRuleInternal(FlowRule flowRule) { 189 private synchronized void deleteFlowRuleInternal(FlowRule flowRule) {
185 - FlowEntry entry = getFlowEntry(flowRule); 190 + StoredFlowEntry entry = getFlowEntryInternal(flowRule);
186 if (entry == null) { 191 if (entry == null) {
187 return; 192 return;
188 } 193 }
...@@ -215,7 +220,7 @@ public class DistributedFlowRuleStore ...@@ -215,7 +220,7 @@ public class DistributedFlowRuleStore
215 DeviceId did = rule.deviceId(); 220 DeviceId did = rule.deviceId();
216 221
217 // check if this new rule is an update to an existing entry 222 // check if this new rule is an update to an existing entry
218 - FlowEntry stored = getFlowEntry(rule); 223 + StoredFlowEntry stored = getFlowEntryInternal(rule);
219 if (stored != null) { 224 if (stored != null) {
220 stored.setBytes(rule.bytes()); 225 stored.setBytes(rule.bytes());
221 stored.setLife(rule.life()); 226 stored.setLife(rule.life());
...@@ -227,7 +232,8 @@ public class DistributedFlowRuleStore ...@@ -227,7 +232,8 @@ public class DistributedFlowRuleStore
227 return new FlowRuleEvent(Type.RULE_UPDATED, rule); 232 return new FlowRuleEvent(Type.RULE_UPDATED, rule);
228 } 233 }
229 234
230 - flowEntries.put(did, rule); 235 + // TODO: Confirm if this behavior is correct. See SimpleFlowRuleStore
236 + flowEntries.put(did, new DefaultFlowEntry(rule));
231 return null; 237 return null;
232 238
233 // TODO: also update backup. 239 // TODO: also update backup.
......
...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger; ...@@ -5,6 +5,7 @@ import static org.slf4j.LoggerFactory.getLogger;
5 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked; 5 import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked;
6 import static java.util.Collections.unmodifiableCollection; 6 import static java.util.Collections.unmodifiableCollection;
7 7
8 +import java.util.Collection;
8 import java.util.HashSet; 9 import java.util.HashSet;
9 import java.util.Set; 10 import java.util.Set;
10 import java.util.concurrent.ConcurrentHashMap; 11 import java.util.concurrent.ConcurrentHashMap;
...@@ -25,6 +26,7 @@ import org.onlab.onos.net.flow.FlowRuleEvent; ...@@ -25,6 +26,7 @@ import org.onlab.onos.net.flow.FlowRuleEvent;
25 import org.onlab.onos.net.flow.FlowRuleEvent.Type; 26 import org.onlab.onos.net.flow.FlowRuleEvent.Type;
26 import org.onlab.onos.net.flow.FlowRuleStore; 27 import org.onlab.onos.net.flow.FlowRuleStore;
27 import org.onlab.onos.net.flow.FlowRuleStoreDelegate; 28 import org.onlab.onos.net.flow.FlowRuleStoreDelegate;
29 +import org.onlab.onos.net.flow.StoredFlowEntry;
28 import org.onlab.onos.store.AbstractStore; 30 import org.onlab.onos.store.AbstractStore;
29 import org.onlab.util.NewConcurrentHashMap; 31 import org.onlab.util.NewConcurrentHashMap;
30 import org.slf4j.Logger; 32 import org.slf4j.Logger;
...@@ -43,7 +45,7 @@ public class SimpleFlowRuleStore ...@@ -43,7 +45,7 @@ public class SimpleFlowRuleStore
43 45
44 // inner Map is Device flow table 46 // inner Map is Device flow table
45 // Assumption: FlowId cannot have synonyms 47 // Assumption: FlowId cannot have synonyms
46 - private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, FlowEntry>> 48 + private final ConcurrentMap<DeviceId, ConcurrentMap<FlowId, StoredFlowEntry>>
47 flowEntries = new ConcurrentHashMap<>(); 49 flowEntries = new ConcurrentHashMap<>();
48 50
49 @Activate 51 @Activate
...@@ -61,14 +63,14 @@ public class SimpleFlowRuleStore ...@@ -61,14 +63,14 @@ public class SimpleFlowRuleStore
61 @Override 63 @Override
62 public int getFlowRuleCount() { 64 public int getFlowRuleCount() {
63 int sum = 0; 65 int sum = 0;
64 - for (ConcurrentMap<FlowId, FlowEntry> ft : flowEntries.values()) { 66 + for (ConcurrentMap<FlowId, StoredFlowEntry> ft : flowEntries.values()) {
65 sum += ft.size(); 67 sum += ft.size();
66 } 68 }
67 return sum; 69 return sum;
68 } 70 }
69 71
70 - private static NewConcurrentHashMap<FlowId, FlowEntry> lazyEmptyFlowTable() { 72 + private static NewConcurrentHashMap<FlowId, StoredFlowEntry> lazyEmptyFlowTable() {
71 - return NewConcurrentHashMap.<FlowId, FlowEntry>ifNeeded(); 73 + return NewConcurrentHashMap.<FlowId, StoredFlowEntry>ifNeeded();
72 } 74 }
73 75
74 /** 76 /**
...@@ -77,12 +79,12 @@ public class SimpleFlowRuleStore ...@@ -77,12 +79,12 @@ public class SimpleFlowRuleStore
77 * @param deviceId identifier of the device 79 * @param deviceId identifier of the device
78 * @return Map representing Flow Table of given device. 80 * @return Map representing Flow Table of given device.
79 */ 81 */
80 - private ConcurrentMap<FlowId, FlowEntry> getFlowTable(DeviceId deviceId) { 82 + private ConcurrentMap<FlowId, StoredFlowEntry> getFlowTable(DeviceId deviceId) {
81 return createIfAbsentUnchecked(flowEntries, 83 return createIfAbsentUnchecked(flowEntries,
82 deviceId, lazyEmptyFlowTable()); 84 deviceId, lazyEmptyFlowTable());
83 } 85 }
84 86
85 - private FlowEntry getFlowEntry(DeviceId deviceId, FlowId flowId) { 87 + private StoredFlowEntry getFlowEntry(DeviceId deviceId, FlowId flowId) {
86 return getFlowTable(deviceId).get(flowId); 88 return getFlowTable(deviceId).get(flowId);
87 } 89 }
88 90
...@@ -93,7 +95,8 @@ public class SimpleFlowRuleStore ...@@ -93,7 +95,8 @@ public class SimpleFlowRuleStore
93 95
94 @Override 96 @Override
95 public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) { 97 public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
96 - return unmodifiableCollection(getFlowTable(deviceId).values()); 98 + return unmodifiableCollection((Collection<? extends FlowEntry>)
99 + getFlowTable(deviceId).values());
97 } 100 }
98 101
99 @Override 102 @Override
...@@ -101,7 +104,7 @@ public class SimpleFlowRuleStore ...@@ -101,7 +104,7 @@ public class SimpleFlowRuleStore
101 104
102 Set<FlowRule> rules = new HashSet<>(); 105 Set<FlowRule> rules = new HashSet<>();
103 for (DeviceId did : flowEntries.keySet()) { 106 for (DeviceId did : flowEntries.keySet()) {
104 - ConcurrentMap<FlowId, FlowEntry> ft = getFlowTable(did); 107 + ConcurrentMap<FlowId, StoredFlowEntry> ft = getFlowTable(did);
105 for (FlowEntry fe : ft.values()) { 108 for (FlowEntry fe : ft.values()) {
106 if (fe.appId() == appId.id()) { 109 if (fe.appId() == appId.id()) {
107 rules.add(fe); 110 rules.add(fe);
...@@ -117,7 +120,7 @@ public class SimpleFlowRuleStore ...@@ -117,7 +120,7 @@ public class SimpleFlowRuleStore
117 } 120 }
118 121
119 private boolean storeFlowRuleInternal(FlowRule rule) { 122 private boolean storeFlowRuleInternal(FlowRule rule) {
120 - FlowEntry f = new DefaultFlowEntry(rule); 123 + StoredFlowEntry f = new DefaultFlowEntry(rule);
121 final DeviceId did = f.deviceId(); 124 final DeviceId did = f.deviceId();
122 final FlowId fid = f.id(); 125 final FlowId fid = f.id();
123 FlowEntry existing = getFlowTable(did).putIfAbsent(fid, f); 126 FlowEntry existing = getFlowTable(did).putIfAbsent(fid, f);
...@@ -133,7 +136,7 @@ public class SimpleFlowRuleStore ...@@ -133,7 +136,7 @@ public class SimpleFlowRuleStore
133 @Override 136 @Override
134 public void deleteFlowRule(FlowRule rule) { 137 public void deleteFlowRule(FlowRule rule) {
135 138
136 - FlowEntry entry = getFlowEntry(rule.deviceId(), rule.id()); 139 + StoredFlowEntry entry = getFlowEntry(rule.deviceId(), rule.id());
137 if (entry == null) { 140 if (entry == null) {
138 //log.warn("Cannot find rule {}", rule); 141 //log.warn("Cannot find rule {}", rule);
139 return; 142 return;
...@@ -146,7 +149,7 @@ public class SimpleFlowRuleStore ...@@ -146,7 +149,7 @@ public class SimpleFlowRuleStore
146 @Override 149 @Override
147 public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) { 150 public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
148 // check if this new rule is an update to an existing entry 151 // check if this new rule is an update to an existing entry
149 - FlowEntry stored = getFlowEntry(rule.deviceId(), rule.id()); 152 + StoredFlowEntry stored = getFlowEntry(rule.deviceId(), rule.id());
150 if (stored != null) { 153 if (stored != null) {
151 synchronized (stored) { 154 synchronized (stored) {
152 stored.setBytes(rule.bytes()); 155 stored.setBytes(rule.bytes());
...@@ -174,7 +177,7 @@ public class SimpleFlowRuleStore ...@@ -174,7 +177,7 @@ public class SimpleFlowRuleStore
174 // This is where one could mark a rule as removed and still keep it in the store. 177 // This is where one could mark a rule as removed and still keep it in the store.
175 final DeviceId did = rule.deviceId(); 178 final DeviceId did = rule.deviceId();
176 179
177 - ConcurrentMap<FlowId, FlowEntry> ft = getFlowTable(did); 180 + ConcurrentMap<FlowId, StoredFlowEntry> ft = getFlowTable(did);
178 if (ft.remove(rule.id(), rule)) { 181 if (ft.remove(rule.id(), rule)) {
179 return new FlowRuleEvent(RULE_REMOVED, rule); 182 return new FlowRuleEvent(RULE_REMOVED, rule);
180 } else { 183 } else {
......