Madan Jampani

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

......@@ -5,7 +5,7 @@ import java.util.SortedSet;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
/**
* Device ID completer.
......@@ -16,7 +16,7 @@ public class FlowRuleStatusCompleter implements Completer {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
FlowRuleState[] states = FlowRuleState.values();
FlowEntryState[] states = FlowEntryState.values();
SortedSet<String> strings = delegate.getStrings();
for (int i = 0; i < states.length; i++) {
strings.add(states[i].toString().toLowerCase());
......
......@@ -13,8 +13,8 @@ import org.onlab.onos.cli.Comparators;
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.FlowRule;
import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRuleService;
import com.google.common.collect.Maps;
......@@ -45,7 +45,7 @@ public class FlowsListCommand extends AbstractShellCommand {
protected void execute() {
DeviceService deviceService = get(DeviceService.class);
FlowRuleService service = get(FlowRuleService.class);
Map<Device, List<FlowRule>> flows = getSortedFlows(deviceService, service);
Map<Device, List<FlowEntry>> flows = getSortedFlows(deviceService, service);
for (Device d : flows.keySet()) {
printFlows(d, flows.get(d));
}
......@@ -57,12 +57,12 @@ public class FlowsListCommand extends AbstractShellCommand {
* @param service device service
* @return sorted device list
*/
protected Map<Device, List<FlowRule>> getSortedFlows(DeviceService deviceService, FlowRuleService service) {
Map<Device, List<FlowRule>> flows = Maps.newHashMap();
List<FlowRule> rules;
FlowRuleState s = null;
protected Map<Device, List<FlowEntry>> getSortedFlows(DeviceService deviceService, FlowRuleService service) {
Map<Device, List<FlowEntry>> flows = Maps.newHashMap();
List<FlowEntry> rules;
FlowEntryState s = null;
if (state != null && !state.equals("any")) {
s = FlowRuleState.valueOf(state.toUpperCase());
s = FlowEntryState.valueOf(state.toUpperCase());
}
Iterable<Device> devices = uri == null ? deviceService.getDevices() :
Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
......@@ -71,7 +71,7 @@ public class FlowsListCommand extends AbstractShellCommand {
rules = newArrayList(service.getFlowEntries(d.id()));
} else {
rules = newArrayList();
for (FlowRule f : service.getFlowEntries(d.id())) {
for (FlowEntry f : service.getFlowEntries(d.id())) {
if (f.state().equals(s)) {
rules.add(f);
}
......@@ -88,13 +88,13 @@ public class FlowsListCommand extends AbstractShellCommand {
* @param d the device
* @param flows the set of flows for that device.
*/
protected void printFlows(Device d, List<FlowRule> flows) {
protected void printFlows(Device d, List<FlowEntry> flows) {
print("Device: " + d.id());
if (flows == null | flows.isEmpty()) {
print(" %s", "No flows.");
return;
}
for (FlowRule f : flows) {
for (FlowEntry f : flows) {
print(FMT, Long.toHexString(f.id().value()), f.state(), f.bytes(),
f.packets(), f.life(), f.priority());
print(SFMT, f.selector().criteria());
......
package org.onlab.onos.net.flow;
import static com.google.common.base.MoreObjects.toStringHelper;
import static org.slf4j.LoggerFactory.getLogger;
import org.onlab.onos.net.DeviceId;
import org.slf4j.Logger;
public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
private final Logger log = getLogger(getClass());
private long life;
private long packets;
private long bytes;
private FlowEntryState state;
private long lastSeen = -1;
public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority, FlowEntryState state,
long life, long packets, long bytes, long flowId,
int timeout) {
super(deviceId, selector, treatment, priority, flowId, timeout);
this.state = state;
this.life = life;
this.packets = packets;
this.bytes = bytes;
this.lastSeen = System.currentTimeMillis();
}
public DefaultFlowEntry(FlowRule rule, FlowEntryState state,
long life, long packets, long bytes) {
super(rule);
this.state = state;
this.life = life;
this.packets = packets;
this.bytes = bytes;
this.lastSeen = System.currentTimeMillis();
}
public DefaultFlowEntry(FlowRule rule) {
super(rule);
this.state = FlowEntryState.PENDING_ADD;
this.life = 0;
this.packets = 0;
this.bytes = 0;
this.lastSeen = System.currentTimeMillis();
}
@Override
public long life() {
return life;
}
@Override
public long packets() {
return packets;
}
@Override
public long bytes() {
return bytes;
}
@Override
public FlowEntryState state() {
return this.state;
}
@Override
public long lastSeen() {
return lastSeen;
}
@Override
public void setLastSeen() {
this.lastSeen = System.currentTimeMillis();
}
@Override
public void setState(FlowEntryState newState) {
this.state = newState;
}
@Override
public void setLife(long life) {
this.life = life;
}
@Override
public void setPackets(long packets) {
this.packets = packets;
}
@Override
public void setBytes(long bytes) {
this.bytes = bytes;
}
@Override
public String toString() {
return toStringHelper(this)
.add("rule", super.toString())
.add("state", state)
.toString();
}
}
......@@ -18,10 +18,6 @@ public class DefaultFlowRule implements FlowRule {
private final TrafficSelector selector;
private final TrafficTreatment treatment;
private final long created;
private final long life;
private final long packets;
private final long bytes;
private final FlowRuleState state;
private final FlowId id;
......@@ -29,90 +25,50 @@ public class DefaultFlowRule implements FlowRule {
private final int timeout;
/**
* Creates a flow rule given the following paremeters.
* @param deviceId the device where the rule should be installed
* @param selector the traffic selection
* @param treatment how the seleted traffic should be handled
* @param priority the rule priority cannot be less than FlowRule.MIN_PRIORITY
* @param state the state in which the rule is
* @param life how long it has existed for (ms)
* @param packets number of packets it has seen
* @param bytes number of bytes it has seen
* @param flowId the identifier
* @param timeout the rule's timeout (idle) not to exceed
* FlowRule.MAX_TIMEOUT of idle time
*/
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority, FlowRuleState state,
long life, long packets, long bytes, long flowId,
TrafficTreatment treatment, int priority, long flowId,
int timeout) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.state = state;
this.timeout = timeout;
this.created = System.currentTimeMillis();
this.appId = ApplicationId.valueOf((int) (flowId >> 32));
this.id = FlowId.valueOf(flowId);
this.life = life;
this.packets = packets;
this.bytes = bytes;
this.created = System.currentTimeMillis();
this.timeout = timeout;
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatement, int priority, ApplicationId appId,
int timeout) {
this(deviceId, selector, treatement, priority,
FlowRuleState.CREATED, appId, timeout);
}
public DefaultFlowRule(FlowRule rule, FlowRuleState state) {
this(rule.deviceId(), rule.selector(), rule.treatment(),
rule.priority(), state, rule.id(), rule.appId(),
rule.timeout());
}
private DefaultFlowRule(DeviceId deviceId,
TrafficSelector selector, TrafficTreatment treatment,
int priority, FlowRuleState state, ApplicationId appId,
int timeout) {
if (priority < MIN_PRIORITY) {
if (priority < FlowRule.MIN_PRIORITY) {
throw new IllegalArgumentException("Priority cannot be less than " + MIN_PRIORITY);
}
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.state = state;
this.life = 0;
this.packets = 0;
this.bytes = 0;
this.treatment = treatement;
this.appId = appId;
this.timeout = timeout;
this.created = System.currentTimeMillis();
this.id = FlowId.valueOf((((long) appId().id()) << 32) | (this.hash() & 0xffffffffL));
this.created = System.currentTimeMillis();
}
private DefaultFlowRule(DeviceId deviceId,
TrafficSelector selector, TrafficTreatment treatment,
int priority, FlowRuleState state, FlowId flowId, ApplicationId appId,
int timeout) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.state = state;
this.life = 0;
this.packets = 0;
this.bytes = 0;
this.appId = appId;
this.id = flowId;
this.timeout = timeout;
public DefaultFlowRule(FlowRule rule) {
this.deviceId = rule.deviceId();
this.priority = rule.priority();
this.selector = rule.selector();
this.treatment = rule.treatment();
this.appId = rule.appId();
this.id = rule.id();
this.timeout = rule.timeout();
this.created = System.currentTimeMillis();
}
......@@ -146,26 +102,6 @@ public class DefaultFlowRule implements FlowRule {
return treatment;
}
@Override
public long life() {
return life;
}
@Override
public long packets() {
return packets;
}
@Override
public long bytes() {
return bytes;
}
@Override
public FlowRuleState state() {
return this.state;
}
@Override
/*
......@@ -213,7 +149,6 @@ public class DefaultFlowRule implements FlowRule {
.add("selector", selector.criteria())
.add("treatment", treatment == null ? "N/A" : treatment.instructions())
.add("created", created)
.add("state", state)
.toString();
}
......
package org.onlab.onos.net.flow;
/**
* Represents a generalized match &amp; action pair to be applied to
* an infrastucture device.
*/
public interface FlowEntry extends FlowRule {
public enum FlowEntryState {
/**
* Indicates that this rule has been submitted for addition.
* Not necessarily in the flow table.
*/
PENDING_ADD,
/**
* Rule has been added which means it is in the flow table.
*/
ADDED,
/**
* Flow has been marked for removal, might still be in flow table.
*/
PENDING_REMOVE,
/**
* Flow has been removed from flow table and can be purged.
*/
REMOVED
}
/**
* Returns the flow entry state.
*
* @return flow entry state
*/
FlowEntryState state();
/**
* Returns the number of milliseconds this flow rule has been applied.
*
* @return number of millis
*/
long life();
/**
* Returns the number of packets this flow rule has matched.
*
* @return number of packets
*/
long packets();
/**
* Returns the number of bytes this flow rule has matched.
*
* @return number of bytes
*/
long bytes();
/**
* When this flow entry was last deemed active.
* @return epoch time of last activity
*/
long lastSeen();
/**
* Sets the last active epoch time.
*/
void setLastSeen();
/**
* Sets the new state for this entry.
* @param newState new flow entry state.
*/
void setState(FlowEntryState newState);
/**
* Sets how long this entry has been entered in the system.
* @param life epoch time
*/
void setLife(long life);
/**
* Number of packets seen by this entry.
* @param packets a long value
*/
void setPackets(long packets);
/**
* Number of bytes seen by this rule.
* @param bytes a long value
*/
void setBytes(long bytes);
}
......@@ -12,41 +12,6 @@ public interface FlowRule {
static final int MAX_TIMEOUT = 60;
static final int MIN_PRIORITY = 0;
public enum FlowRuleState {
/**
* Indicates that this rule has been created.
*/
CREATED,
/**
* Indicates that this rule has been submitted for addition.
* Not necessarily in the flow table.
*/
PENDING_ADD,
/**
* Rule has been added which means it is in the flow table.
*/
ADDED,
/**
* Flow has been marked for removal, might still be in flow table.
*/
PENDING_REMOVE,
/**
* Flow has been removed from flow table and can be purged.
*/
REMOVED
}
/**
* Returns the flow rule state.
*
* @return flow rule state
*/
FlowRuleState state();
//TODO: build cookie value
/**
* Returns the ID of this flow.
......@@ -93,27 +58,6 @@ public interface FlowRule {
TrafficTreatment treatment();
/**
* Returns the number of milliseconds this flow rule has been applied.
*
* @return number of millis
*/
long life();
/**
* Returns the number of packets this flow rule has matched.
*
* @return number of packets
*/
long packets();
/**
* Returns the number of bytes this flow rule has matched.
*
* @return number of bytes
*/
long bytes();
/**
* Returns the timeout for this flow requested by an application.
* @return integer value of the timeout
*/
......
......@@ -14,7 +14,7 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide
*
* @param flowRule information about the removed flow
*/
void flowRemoved(FlowRule flowRule);
void flowRemoved(FlowEntry flowEntry);
/**
* Pushes the collection of flow entries currently applied on the given
......@@ -22,7 +22,7 @@ public interface FlowRuleProviderService extends ProviderService<FlowRuleProvide
*
* @param flowRules collection of flow rules
*/
void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowRules);
void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries);
......
......@@ -20,7 +20,7 @@ public interface FlowRuleService {
* @param deviceId device identifier
* @return collection of flow rules
*/
Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
// TODO: add createFlowRule factory method and execute operations method
......
......@@ -14,7 +14,7 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
* @param rule the rule to look for
* @return a flow rule
*/
FlowRule getFlowRule(FlowRule rule);
FlowEntry getFlowEntry(FlowRule rule);
/**
* Returns the flow entries associated with a device.
......@@ -22,7 +22,7 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
* @param deviceId the device ID
* @return the flow entries
*/
Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
/**
* Returns the flow entries associated with an application.
......@@ -30,7 +30,7 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
* @param appId the application id
* @return the flow entries
*/
Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId);
Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId);
/**
* Stores a new flow rule without generating events.
......@@ -40,7 +40,8 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
void storeFlowRule(FlowRule rule);
/**
* Deletes a flow rule without generating events.
* Marks a flow rule for deletion. Actual deletion will occur
* when the provider indicates that the flow has been removed.
*
* @param rule the flow rule to delete
*/
......@@ -52,12 +53,12 @@ public interface FlowRuleStore extends Store<FlowRuleEvent, FlowRuleStoreDelegat
* @param rule the flow rule to add or update
* @return flow_added event, or null if just an update
*/
FlowRuleEvent addOrUpdateFlowRule(FlowRule rule);
FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule);
/**
* @param rule the flow rule to remove
* @param rule the flow entry to remove
* @return flow_removed event, or null if nothing removed
*/
FlowRuleEvent removeFlowRule(FlowRule rule);
FlowRuleEvent removeFlowRule(FlowEntry rule);
}
......
......@@ -5,8 +5,6 @@ import static org.slf4j.LoggerFactory.getLogger;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
......@@ -20,6 +18,7 @@ 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.FlowEntry;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleListener;
......@@ -61,8 +60,6 @@ implements FlowRuleService, FlowRuleProviderRegistry {
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected DeviceService deviceService;
private final Map<FlowRule, Long> idleTime = new ConcurrentHashMap<>();
@Activate
public void activate() {
store.setDelegate(delegate);
......@@ -78,7 +75,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
@Override
public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
return store.getFlowEntries(deviceId);
}
......@@ -88,7 +85,6 @@ implements FlowRuleService, FlowRuleProviderRegistry {
FlowRule f = flowRules[i];
final Device device = deviceService.getDevice(f.deviceId());
final FlowRuleProvider frp = getProvider(device.providerId());
idleTime.put(f, System.currentTimeMillis());
store.storeFlowRule(f);
frp.applyFlowRule(f);
}
......@@ -103,7 +99,6 @@ implements FlowRuleService, FlowRuleProviderRegistry {
f = flowRules[i];
device = deviceService.getDevice(f.deviceId());
frp = getProvider(device.providerId());
idleTime.remove(f);
store.deleteFlowRule(f);
frp.removeFlowRule(f);
}
......@@ -125,7 +120,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
@Override
public Iterable<FlowRule> getFlowRulesById(ApplicationId id) {
return store.getFlowEntriesByAppId(id);
return store.getFlowRulesByAppId(id);
}
@Override
......@@ -153,15 +148,15 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
@Override
public void flowRemoved(FlowRule flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
public void flowRemoved(FlowEntry flowEntry) {
checkNotNull(flowEntry, FLOW_RULE_NULL);
checkValidity();
FlowRule stored = store.getFlowRule(flowRule);
FlowEntry stored = store.getFlowEntry(flowEntry);
if (stored == null) {
log.info("Rule already evicted from store: {}", flowRule);
log.info("Rule already evicted from store: {}", flowEntry);
return;
}
Device device = deviceService.getDevice(flowRule.deviceId());
Device device = deviceService.getDevice(flowEntry.deviceId());
FlowRuleProvider frp = getProvider(device.providerId());
FlowRuleEvent event = null;
switch (stored.state()) {
......@@ -171,20 +166,20 @@ implements FlowRuleService, FlowRuleProviderRegistry {
break;
case PENDING_REMOVE:
case REMOVED:
event = store.removeFlowRule(flowRule);
event = store.removeFlowRule(stored);
break;
default:
break;
}
if (event != null) {
log.debug("Flow {} removed", flowRule);
log.debug("Flow {} removed", flowEntry);
post(event);
}
}
private void flowMissing(FlowRule flowRule) {
private void flowMissing(FlowEntry flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
checkValidity();
Device device = deviceService.getDevice(flowRule.deviceId());
......@@ -220,36 +215,37 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
private void flowAdded(FlowRule flowRule) {
checkNotNull(flowRule, FLOW_RULE_NULL);
private void flowAdded(FlowEntry flowEntry) {
checkNotNull(flowEntry, FLOW_RULE_NULL);
checkValidity();
if (idleTime.containsKey(flowRule) &&
checkRuleLiveness(flowRule, store.getFlowRule(flowRule))) {
if (checkRuleLiveness(flowEntry, store.getFlowEntry(flowEntry))) {
FlowRuleEvent event = store.addOrUpdateFlowRule(flowRule);
FlowRuleEvent event = store.addOrUpdateFlowRule(flowEntry);
if (event == null) {
log.debug("No flow store event generated.");
} else {
log.debug("Flow {} {}", flowRule, event.type());
log.debug("Flow {} {}", flowEntry, event.type());
post(event);
}
} else {
removeFlowRules(flowRule);
removeFlowRules(flowEntry);
}
}
private boolean checkRuleLiveness(FlowRule swRule, FlowRule storedRule) {
private boolean checkRuleLiveness(FlowEntry swRule, FlowEntry storedRule) {
if (storedRule == null) {
return false;
}
long timeout = storedRule.timeout() * 1000;
Long currentTime = System.currentTimeMillis();
if (storedRule.packets() != swRule.packets()) {
idleTime.put(swRule, currentTime);
storedRule.setLastSeen();
return true;
}
if ((currentTime - idleTime.get(swRule)) <= timeout) {
idleTime.put(swRule, currentTime);
if ((currentTime - storedRule.lastSeen()) <= timeout) {
return true;
}
return false;
......@@ -263,13 +259,13 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
@Override
public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowRule> flowEntries) {
List<FlowRule> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
List<FlowEntry> storedRules = Lists.newLinkedList(store.getFlowEntries(deviceId));
Iterator<FlowRule> switchRulesIterator = flowEntries.iterator();
Iterator<FlowEntry> switchRulesIterator = flowEntries.iterator();
while (switchRulesIterator.hasNext()) {
FlowRule rule = switchRulesIterator.next();
FlowEntry rule = switchRulesIterator.next();
if (storedRules.remove(rule)) {
// we both have the rule, let's update some info then.
flowAdded(rule);
......@@ -278,7 +274,7 @@ implements FlowRuleService, FlowRuleProviderRegistry {
extraneousFlow(rule);
}
}
for (FlowRule rule : storedRules) {
for (FlowEntry rule : storedRules) {
// there are rules in the store that aren't on the switch
flowMissing(rule);
......
......@@ -27,9 +27,11 @@ import org.onlab.onos.net.Port;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.device.DeviceListener;
import org.onlab.onos.net.device.DeviceService;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
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;
......@@ -103,9 +105,6 @@ public class FlowRuleManagerTest {
return new DefaultFlowRule(DID, ts, tr, 10, appId, TIMEOUT);
}
private FlowRule flowRule(FlowRule rule, FlowRuleState state) {
return new DefaultFlowRule(rule, state);
}
private FlowRule addFlowRule(int hval) {
FlowRule rule = flowRule(hval, hval);
......@@ -143,24 +142,26 @@ public class FlowRuleManagerTest {
FlowRule f1 = addFlowRule(1);
FlowRule f2 = addFlowRule(2);
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
assertEquals("2 rules should exist", 2, flowCount());
providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2));
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
validateEvents(RULE_ADDED, RULE_ADDED);
addFlowRule(1);
assertEquals("should still be 2 rules", 2, flowCount());
providerService.pushFlowMetrics(DID, ImmutableList.of(f1));
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1));
validateEvents(RULE_UPDATED);
}
//backing store is sensitive to the order of additions/removals
private boolean validateState(FlowRuleState... state) {
Iterable<FlowRule> rules = service.getFlowEntries(DID);
private boolean validateState(FlowEntryState... state) {
Iterable<FlowEntry> rules = service.getFlowEntries(DID);
int i = 0;
for (FlowRule f : rules) {
for (FlowEntry f : rules) {
if (f.state() != state[i]) {
return false;
}
......@@ -181,8 +182,8 @@ public class FlowRuleManagerTest {
mgr.applyFlowRules(r1, r2, r3);
assertEquals("3 rules should exist", 3, flowCount());
assertTrue("Entries should be pending add.",
validateState(FlowRuleState.PENDING_ADD, FlowRuleState.PENDING_ADD,
FlowRuleState.PENDING_ADD));
validateState(FlowEntryState.PENDING_ADD, FlowEntryState.PENDING_ADD,
FlowEntryState.PENDING_ADD));
}
@Test
......@@ -192,20 +193,21 @@ public class FlowRuleManagerTest {
FlowRule f3 = addFlowRule(3);
assertEquals("3 rules should exist", 3, flowCount());
providerService.pushFlowMetrics(DID, ImmutableList.of(f1, f2, f3));
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
FlowEntry fe3 = new DefaultFlowEntry(f3);
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2, fe3));
validateEvents(RULE_ADDED, RULE_ADDED, RULE_ADDED);
FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
FlowRule rem2 = flowRule(f2, FlowRuleState.REMOVED);
mgr.removeFlowRules(rem1, rem2);
mgr.removeFlowRules(f1, f2);
//removing from north, so no events generated
validateEvents();
assertEquals("3 rule should exist", 3, flowCount());
assertTrue("Entries should be pending remove.",
validateState(FlowRuleState.CREATED, FlowRuleState.PENDING_REMOVE,
FlowRuleState.PENDING_REMOVE));
validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE,
FlowEntryState.ADDED));
mgr.removeFlowRules(rem1);
mgr.removeFlowRules(f1);
assertEquals("3 rule should still exist", 3, flowCount());
}
......@@ -213,21 +215,24 @@ public class FlowRuleManagerTest {
public void flowRemoved() {
FlowRule f1 = addFlowRule(1);
FlowRule f2 = addFlowRule(2);
providerService.pushFlowMetrics(f1.deviceId(), ImmutableList.of(f1, f2));
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
providerService.pushFlowMetrics(DID, ImmutableList.of(fe1, fe2));
service.removeFlowRules(f1);
FlowRule rem1 = flowRule(f1, FlowRuleState.REMOVED);
providerService.flowRemoved(rem1);
fe1.setState(FlowEntryState.REMOVED);
providerService.flowRemoved(fe1);
validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
providerService.flowRemoved(rem1);
providerService.flowRemoved(fe1);
validateEvents();
FlowRule f3 = flowRule(3, 3);
FlowEntry fe3 = new DefaultFlowEntry(f3);
service.applyFlowRules(f3);
providerService.pushFlowMetrics(f3.deviceId(), Collections.singletonList(f3));
providerService.pushFlowMetrics(DID, Collections.singletonList(fe3));
validateEvents(RULE_ADDED);
providerService.flowRemoved(f3);
providerService.flowRemoved(fe3);
validateEvents();
}
......@@ -237,17 +242,20 @@ public class FlowRuleManagerTest {
FlowRule f2 = flowRule(2, 2);
FlowRule f3 = flowRule(3, 3);
mgr.applyFlowRules(f1, f2, f3);
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
mgr.applyFlowRules(f1, f2, f3);
FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
//FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
//FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
assertTrue("Entries should be added.",
validateState(FlowRuleState.PENDING_ADD, FlowRuleState.ADDED,
FlowRuleState.ADDED));
validateState(FlowEntryState.ADDED, FlowEntryState.ADDED,
FlowEntryState.PENDING_ADD));
validateEvents(RULE_ADDED, RULE_ADDED);
}
......@@ -259,11 +267,15 @@ public class FlowRuleManagerTest {
FlowRule f3 = flowRule(3, 3);
mgr.applyFlowRules(f1, f2);
FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
// FlowRule updatedF3 = flowRule(f3, FlowRuleState.ADDED);
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
FlowEntry fe3 = new DefaultFlowEntry(f3);
providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2, updatedF3));
providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2, fe3));
validateEvents(RULE_ADDED, RULE_ADDED);
......@@ -279,13 +291,16 @@ public class FlowRuleManagerTest {
FlowRule f2 = flowRule(2, 2);
FlowRule f3 = flowRule(3, 3);
FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
// FlowRule updatedF1 = flowRule(f1, FlowRuleState.ADDED);
// FlowRule updatedF2 = flowRule(f2, FlowRuleState.ADDED);
FlowEntry fe1 = new DefaultFlowEntry(f1);
FlowEntry fe2 = new DefaultFlowEntry(f2);
mgr.applyFlowRules(f1, f2, f3);
mgr.removeFlowRules(f3);
providerService.pushFlowMetrics(DID, Lists.newArrayList(updatedF1, updatedF2));
providerService.pushFlowMetrics(DID, Lists.newArrayList(fe1, fe2));
validateEvents(RULE_ADDED, RULE_ADDED, RULE_REMOVED);
......@@ -312,7 +327,7 @@ public class FlowRuleManagerTest {
//only check that we are in pending remove. Events and actual remove state will
// be set by flowRemoved call.
validateState(FlowRuleState.PENDING_REMOVE, FlowRuleState.PENDING_REMOVE);
validateState(FlowEntryState.PENDING_REMOVE, FlowEntryState.PENDING_REMOVE);
}
private static class TestListener implements FlowRuleListener {
......
package org.onlab.onos.store.flow.impl;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -13,9 +12,10 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
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.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
......@@ -30,18 +30,18 @@ import com.google.common.collect.Multimap;
/**
* Manages inventory of flow rules using trivial in-memory implementation.
*/
//FIXME: I LIE I AM NOT DISTRIBUTED
//FIXME I LIE. I AIN'T DISTRIBUTED
@Component(immediate = true)
@Service
public class DistributedFlowRuleStore
extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
implements FlowRuleStore {
extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
implements FlowRuleStore {
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
private final Multimap<DeviceId, FlowRule> flowEntries =
ArrayListMultimap.<DeviceId, FlowRule>create();
private final Multimap<DeviceId, FlowEntry> flowEntries =
ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
......@@ -58,8 +58,8 @@ implements FlowRuleStore {
@Override
public synchronized FlowRule getFlowRule(FlowRule rule) {
for (FlowRule f : flowEntries.get(rule.deviceId())) {
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
......@@ -68,8 +68,8 @@ implements FlowRuleStore {
}
@Override
public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Collection<FlowRule> rules = flowEntries.get(deviceId);
public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
......@@ -77,7 +77,7 @@ implements FlowRuleStore {
}
@Override
public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
......@@ -87,7 +87,7 @@ implements FlowRuleStore {
@Override
public synchronized void storeFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
......@@ -97,57 +97,41 @@ implements FlowRuleStore {
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
DeviceId did = f.deviceId();
/*
* find the rule and mark it for deletion.
* Ultimately a flow removed will come remove it.
*/
if (flowEntries.containsEntry(did, f)) {
//synchronized (flowEntries) {
flowEntries.remove(did, f);
flowEntries.put(did, f);
flowEntriesById.remove(rule.appId(), rule);
//}
FlowEntry entry = getFlowEntry(rule);
if (entry == null) {
return;
}
entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
if (flowEntries.containsEntry(did, rule)) {
//synchronized (flowEntries) {
// Multimaps support duplicates so we have to remove our rule
// and replace it with the current version.
flowEntries.remove(did, rule);
flowEntries.put(did, rule);
//}
FlowEntry stored = getFlowEntry(rule);
if (stored != null) {
stored.setBytes(rule.bytes());
stored.setLife(rule.life());
stored.setPackets(rule.packets());
if (stored.state() == FlowEntryState.PENDING_ADD) {
stored.setState(FlowEntryState.ADDED);
return new FlowRuleEvent(Type.RULE_ADDED, rule);
}
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
flowEntries.put(did, rule);
return new FlowRuleEvent(RULE_ADDED, rule);
return null;
}
@Override
public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
//synchronized (this) {
public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
// This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
//}
}
}
......
package org.onlab.onos.store.flow.impl;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_ADDED;
import static org.onlab.onos.net.flow.FlowRuleEvent.Type.RULE_REMOVED;
import static org.slf4j.LoggerFactory.getLogger;
......@@ -13,9 +12,10 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
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.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
......@@ -28,20 +28,20 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
/**
* TEMPORARY: Manages inventory of flow rules using distributed store implementation.
* Manages inventory of flow rules using trivial in-memory implementation.
*/
//FIXME: I LIE I AM NOT DISTRIBUTED
//FIXME I LIE. I AIN'T DISTRIBUTED
@Component(immediate = true)
@Service
public class DistributedFlowRuleStore
extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
implements FlowRuleStore {
extends AbstractStore<FlowRuleEvent, FlowRuleStoreDelegate>
implements FlowRuleStore {
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
private final Multimap<DeviceId, FlowRule> flowEntries =
ArrayListMultimap.<DeviceId, FlowRule>create();
private final Multimap<DeviceId, FlowEntry> flowEntries =
ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
......@@ -58,8 +58,8 @@ implements FlowRuleStore {
@Override
public synchronized FlowRule getFlowRule(FlowRule rule) {
for (FlowRule f : flowEntries.get(rule.deviceId())) {
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
......@@ -68,8 +68,8 @@ implements FlowRuleStore {
}
@Override
public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Collection<FlowRule> rules = flowEntries.get(deviceId);
public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
......@@ -77,7 +77,7 @@ implements FlowRuleStore {
}
@Override
public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
......@@ -87,7 +87,7 @@ implements FlowRuleStore {
@Override
public synchronized void storeFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
......@@ -97,57 +97,41 @@ implements FlowRuleStore {
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
DeviceId did = f.deviceId();
/*
* find the rule and mark it for deletion.
* Ultimately a flow removed will come remove it.
*/
if (flowEntries.containsEntry(did, f)) {
//synchronized (flowEntries) {
flowEntries.remove(did, f);
flowEntries.put(did, f);
flowEntriesById.remove(rule.appId(), rule);
//}
FlowEntry entry = getFlowEntry(rule);
if (entry == null) {
return;
}
entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
if (flowEntries.containsEntry(did, rule)) {
//synchronized (flowEntries) {
// Multimaps support duplicates so we have to remove our rule
// and replace it with the current version.
flowEntries.remove(did, rule);
flowEntries.put(did, rule);
//}
FlowEntry stored = getFlowEntry(rule);
if (stored != null) {
stored.setBytes(rule.bytes());
stored.setLife(rule.life());
stored.setPackets(rule.packets());
if (stored.state() == FlowEntryState.PENDING_ADD) {
stored.setState(FlowEntryState.ADDED);
return new FlowRuleEvent(Type.RULE_ADDED, rule);
}
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
}
flowEntries.put(did, rule);
return new FlowRuleEvent(RULE_ADDED, rule);
return null;
}
@Override
public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
//synchronized (this) {
public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
// This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
//}
}
}
......
......@@ -12,9 +12,10 @@ import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
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.FlowRuleEvent.Type;
import org.onlab.onos.net.flow.FlowRuleStore;
......@@ -38,8 +39,8 @@ public class SimpleFlowRuleStore
private final Logger log = getLogger(getClass());
// store entries as a pile of rules, no info about device tables
private final Multimap<DeviceId, FlowRule> flowEntries =
ArrayListMultimap.<DeviceId, FlowRule>create();
private final Multimap<DeviceId, FlowEntry> flowEntries =
ArrayListMultimap.<DeviceId, FlowEntry>create();
private final Multimap<ApplicationId, FlowRule> flowEntriesById =
ArrayListMultimap.<ApplicationId, FlowRule>create();
......@@ -56,8 +57,8 @@ public class SimpleFlowRuleStore
@Override
public synchronized FlowRule getFlowRule(FlowRule rule) {
for (FlowRule f : flowEntries.get(rule.deviceId())) {
public synchronized FlowEntry getFlowEntry(FlowRule rule) {
for (FlowEntry f : flowEntries.get(rule.deviceId())) {
if (f.equals(rule)) {
return f;
}
......@@ -66,8 +67,8 @@ public class SimpleFlowRuleStore
}
@Override
public synchronized Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
Collection<FlowRule> rules = flowEntries.get(deviceId);
public synchronized Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
Collection<FlowEntry> rules = flowEntries.get(deviceId);
if (rules == null) {
return Collections.emptyList();
}
......@@ -75,7 +76,7 @@ public class SimpleFlowRuleStore
}
@Override
public synchronized Iterable<FlowRule> getFlowEntriesByAppId(ApplicationId appId) {
public synchronized Iterable<FlowRule> getFlowRulesByAppId(ApplicationId appId) {
Collection<FlowRule> rules = flowEntriesById.get(appId);
if (rules == null) {
return Collections.emptyList();
......@@ -85,7 +86,7 @@ public class SimpleFlowRuleStore
@Override
public synchronized void storeFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_ADD);
FlowEntry f = new DefaultFlowEntry(rule);
DeviceId did = f.deviceId();
if (!flowEntries.containsEntry(did, f)) {
flowEntries.put(did, f);
......@@ -95,34 +96,25 @@ public class SimpleFlowRuleStore
@Override
public synchronized void deleteFlowRule(FlowRule rule) {
FlowRule f = new DefaultFlowRule(rule, FlowRuleState.PENDING_REMOVE);
DeviceId did = f.deviceId();
/*
* find the rule and mark it for deletion.
* Ultimately a flow removed will come remove it.
*/
if (flowEntries.containsEntry(did, f)) {
flowEntries.remove(did, f);
flowEntries.put(did, f);
flowEntriesById.remove(rule.appId(), rule);
FlowEntry entry = getFlowEntry(rule);
if (entry == null) {
return;
}
entry.setState(FlowEntryState.PENDING_REMOVE);
}
@Override
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
public synchronized FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
DeviceId did = rule.deviceId();
// check if this new rule is an update to an existing entry
FlowRule stored = getFlowRule(rule);
FlowEntry stored = getFlowEntry(rule);
if (stored != null) {
// Multimaps support duplicates so we have to remove our rule
// and replace it with the current version.
flowEntries.remove(did, rule);
flowEntries.put(did, rule);
if (stored.state() == FlowRuleState.PENDING_ADD) {
stored.setBytes(rule.bytes());
stored.setLife(rule.life());
stored.setPackets(rule.packets());
if (stored.state() == FlowEntryState.PENDING_ADD) {
stored.setState(FlowEntryState.ADDED);
return new FlowRuleEvent(Type.RULE_ADDED, rule);
}
return new FlowRuleEvent(Type.RULE_UPDATED, rule);
......@@ -133,13 +125,12 @@ public class SimpleFlowRuleStore
}
@Override
public synchronized FlowRuleEvent removeFlowRule(FlowRule rule) {
//synchronized (this) {
public synchronized FlowRuleEvent removeFlowRule(FlowEntry rule) {
// This is where one could mark a rule as removed and still keep it in the store.
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
}
//}
}
}
......
......@@ -6,11 +6,13 @@ import java.util.List;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.PortNumber;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.DefaultTrafficSelector;
import org.onlab.onos.net.flow.DefaultTrafficTreatment;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowEntry.FlowEntryState;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRule.FlowRuleState;
import org.onlab.onos.net.flow.TrafficSelector;
import org.onlab.onos.net.flow.TrafficTreatment;
import org.onlab.onos.openflow.controller.Dpid;
......@@ -37,7 +39,7 @@ import org.slf4j.Logger;
import com.google.common.collect.Lists;
public class FlowRuleBuilder {
public class FlowEntryBuilder {
private final Logger log = getLogger(getClass());
private final OFFlowStatsEntry stat;
......@@ -51,7 +53,7 @@ public class FlowRuleBuilder {
private final boolean addedRule;
public FlowRuleBuilder(Dpid dpid, OFFlowStatsEntry entry) {
public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
this.stat = entry;
this.match = entry.getMatch();
this.actions = getActions(entry);
......@@ -60,7 +62,7 @@ public class FlowRuleBuilder {
this.addedRule = true;
}
public FlowRuleBuilder(Dpid dpid, OFFlowRemoved removed) {
public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
this.match = removed.getMatch();
this.removed = removed;
......@@ -71,20 +73,21 @@ public class FlowRuleBuilder {
}
public FlowRule build() {
public FlowEntry build() {
if (addedRule) {
return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), buildTreatment(), stat.getPriority(),
FlowRuleState.ADDED, stat.getDurationSec(),
stat.getPacketCount().getValue(), stat.getByteCount().getValue(),
stat.getCookie().getValue(), stat.getIdleTimeout());
return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
stat.getDurationSec(), stat.getPacketCount().getValue(),
stat.getByteCount().getValue());
} else {
// TODO: revisit potentially.
return new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
FlowRule rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), null, removed.getPriority(),
FlowRuleState.REMOVED, removed.getDurationSec(),
removed.getPacketCount().getValue(), removed.getByteCount().getValue(),
removed.getCookie().getValue(), removed.getIdleTimeout());
return new DefaultFlowEntry(rule, FlowEntryState.REMOVED, removed.getDurationSec(),
removed.getPacketCount().getValue(), removed.getByteCount().getValue());
}
}
......
......@@ -12,6 +12,7 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.ApplicationId;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
......@@ -131,7 +132,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
implements OpenFlowSwitchListener, OpenFlowEventListener {
private final Map<Dpid, FlowStatsCollector> collectors = Maps.newHashMap();
private final Multimap<DeviceId, FlowRule> completeEntries =
private final Multimap<DeviceId, FlowEntry> completeEntries =
ArrayListMultimap.create();
@Override
......@@ -158,7 +159,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
//TODO: make this better
OFFlowRemoved removed = (OFFlowRemoved) msg;
FlowRule fr = new FlowRuleBuilder(dpid, removed).build();
FlowEntry fr = new FlowEntryBuilder(dpid, removed).build();
providerService.flowRemoved(fr);
break;
case STATS_REPLY:
......@@ -188,7 +189,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
for (OFFlowStatsEntry reply : replies.getEntries()) {
if (!tableMissRule(dpid, reply)) {
completeEntries.put(did, new FlowRuleBuilder(dpid, reply).build());
completeEntries.put(did, new FlowEntryBuilder(dpid, reply).build());
}
}
......