Ayaka Koshibe

Consolidated FlowEntry into FlowRule

Change-Id: I349d73abba3336f4c79429efb5717e0a8c374a30
......@@ -169,7 +169,7 @@ public class ReactiveForwarding {
treat.add(Instructions.createOutput(portNumber));
FlowRule f = new DefaultFlowRule(context.inPacket().receivedFrom().deviceId(),
builder.build(), treat.build());
builder.build(), treat.build(), 0);
flowRuleService.applyFlowRules(f);
}
......
package org.onlab.onos.net.flow;
import static com.google.common.base.MoreObjects.toStringHelper;
import org.onlab.onos.net.DeviceId;
public class DefaultFlowEntry extends DefaultFlowRule implements FlowEntry {
private final int priority;
private final long created;
private final FlowId id;
public DefaultFlowEntry(DefaultFlowEntry entry) {
super(entry.deviceId(), entry.selector(), entry.treatment());
this.priority = entry.priority;
this.created = entry.created;
this.id = entry.id;
}
public DefaultFlowEntry(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority) {
super(deviceId, selector, treatment);
this.priority = priority;
this.created = System.currentTimeMillis();
this.id = FlowId.valueOf(this.hashCode());
}
@Override
public FlowId id() {
return null;
}
@Override
public int priority() {
return priority;
}
@Override
public long lifeMillis() {
return (created - System.currentTimeMillis());
}
@Override
public long idleMillis() {
return 0;
}
@Override
public long packets() {
return 0;
}
@Override
public long bytes() {
return 0;
}
@Override
/*
* currently uses the parts that definitely have a defined hashcode...
*
* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
final int prime = 31;
int result = prime * this.deviceId().hashCode();
result = prime * result + this.priority;
result = prime * result + this.selector().hashCode();
result = prime * result + this.treatment().hashCode();
return result;
}
@Override
/*
* The priority and statistics can change on a given treatment and selector
*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object obj) {
if (obj instanceof DefaultFlowEntry) {
DefaultFlowEntry that = (DefaultFlowEntry) obj;
if (!this.deviceId().equals(that.deviceId())) {
return false;
}
if (!(this.priority == that.priority)) {
return false;
}
return super.equals(obj);
}
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("id", id)
.add("deviceId", deviceId())
.add("priority", priority)
.add("selector", selector())
.add("treatment", treatment())
.toString();
}
}
package org.onlab.onos.net.flow;
import static com.google.common.base.MoreObjects.toStringHelper;
import org.onlab.onos.net.DeviceId;
public class DefaultFlowRule implements FlowRule {
private final DeviceId deviceId;
private final int priority;
private final TrafficSelector selector;
private final TrafficTreatment treatment;
private final DeviceId deviceId;
private final FlowId id;
private final long created;
public DefaultFlowRule(DeviceId deviceId,
TrafficSelector selector, TrafficTreatment treatment) {
this.treatment = treatment;
this.selector = selector;
TrafficSelector selector, TrafficTreatment treatment, int priority) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.id = FlowId.valueOf(this.hashCode());
this.created = System.currentTimeMillis();
}
@Override
public FlowId id() {
return id;
}
@Override
public int priority() {
// is this supposed to be 0?
return 0;
return priority;
}
@Override
......@@ -37,6 +50,35 @@ public class DefaultFlowRule implements FlowRule {
}
@Override
public long lifeMillis() {
return (created - System.currentTimeMillis());
}
@Override
public long idleMillis() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long packets() {
// TODO Auto-generated method stub
return 0;
}
@Override
public long bytes() {
// TODO Auto-generated method stub
return 0;
}
@Override
/*
* The priority and statistics can change on a given treatment and selector
*
* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public int hashCode() {
final int prime = 31;
int result = prime * this.deviceId().hashCode();
......@@ -69,5 +111,16 @@ public class DefaultFlowRule implements FlowRule {
return false;
}
@Override
public String toString() {
return toStringHelper(this)
.add("id", id)
.add("deviceId", deviceId)
.add("priority", priority)
.add("selector", selector)
.add("treatment", treatment)
.add("created", created)
.toString();
}
}
......
package org.onlab.onos.net.flow;
/**
* Represents a flow rule and its associated accumulated metrics.
*/
public interface FlowEntry extends FlowRule {
/**
* Returns the ID of this flow.
*
* @return the flow ID
*/
FlowId id();
/**
* Returns the number of milliseconds this flow rule has been applied.
*
* @return number of millis
*/
long lifeMillis();
/**
* Returns the number of milliseconds this flow rule has been idle.
*
* @return number of millis
*/
long idleMillis();
/**
* 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();
}
......@@ -9,6 +9,12 @@ import org.onlab.onos.net.DeviceId;
public interface FlowRule {
//TODO: build cookie value
/**
* Returns the ID of this flow.
*
* @return the flow ID
*/
FlowId id();
/**
* Returns the flow rule priority given in natural order; higher numbers
......@@ -40,4 +46,32 @@ public interface FlowRule {
*/
TrafficTreatment treatment();
/**
* Returns the number of milliseconds this flow rule has been applied.
*
* @return number of millis
*/
long lifeMillis();
/**
* Returns the number of milliseconds this flow rule has been idle.
*
* @return number of millis
*/
long idleMillis();
/**
* 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();
}
......
......@@ -34,6 +34,6 @@ public interface FlowRuleProvider extends Provider {
* @param deviceId device identifier
* @return collection of flow entries
*/
Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId);
Iterable<FlowRule> getFlowMetrics(DeviceId deviceId);
}
......
......@@ -21,7 +21,7 @@ public interface FlowRuleService {
* @param deviceId device identifier
* @return collection of flow rules
*/
Iterable<FlowEntry> getFlowEntries(DeviceId deviceId);
Iterable<FlowRule> getFlowEntries(DeviceId deviceId);
// TODO: add createFlowRule factory method and execute operations method
......@@ -34,7 +34,7 @@ public interface FlowRuleService {
* throws SomeKindOfException that indicates which ones were applied and
* which ones failed
*/
List<FlowEntry> applyFlowRules(FlowRule... flowRules);
List<FlowRule> applyFlowRules(FlowRule... flowRules);
/**
* Removes the specified flow rules from their respective devices. If the
......
......@@ -16,7 +16,6 @@ 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;
......@@ -63,13 +62,13 @@ implements FlowRuleService, FlowRuleProviderRegistry {
}
@Override
public Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
public Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
return store.getFlowEntries(deviceId);
}
@Override
public List<FlowEntry> applyFlowRules(FlowRule... flowRules) {
List<FlowEntry> entries = new ArrayList<FlowEntry>();
public List<FlowRule> applyFlowRules(FlowRule... flowRules) {
List<FlowRule> entries = new ArrayList<FlowRule>();
for (int i = 0; i < flowRules.length; i++) {
FlowRule f = flowRules[i];
......
package org.onlab.onos.net.trivial.flow.impl;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.DefaultFlowEntry;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleEvent;
......@@ -18,7 +17,7 @@ import static org.onlab.onos.net.flow.FlowRuleEvent.Type.*;
public class SimpleFlowRuleStore {
// store entries as a pile of rules, no info about device tables
private final Multimap<DeviceId, FlowEntry> flowEntries = HashMultimap.create();
private final Multimap<DeviceId, FlowRule> flowEntries = HashMultimap.create();
/**
* Returns the flow entries associated with a device.
......@@ -26,19 +25,19 @@ public class SimpleFlowRuleStore {
* @param deviceId the device ID
* @return the flow entries
*/
Iterable<FlowEntry> getFlowEntries(DeviceId deviceId) {
Iterable<FlowRule> getFlowEntries(DeviceId deviceId) {
return ImmutableSet.copyOf(flowEntries.get(deviceId));
}
/**
* Stores a new flow rule, and generates a FlowEntry for it.
* Stores a new flow rule, and generates a FlowRule for it.
*
* @param rule the flow rule to add
* @return a flow entry
*/
FlowEntry storeFlowRule(FlowRule rule) {
FlowRule storeFlowRule(FlowRule rule) {
DeviceId did = rule.deviceId();
FlowEntry entry = new DefaultFlowEntry(did,
FlowRule entry = new DefaultFlowRule(did,
rule.selector(), rule.treatment(), rule.priority());
flowEntries.put(did, entry);
return entry;
......@@ -53,20 +52,14 @@ public class SimpleFlowRuleStore {
FlowRuleEvent addOrUpdateFlowRule(FlowRule rule) {
DeviceId did = rule.deviceId();
FlowEntry entry = new DefaultFlowEntry(
did,
rule.selector(),
rule.treatment(),
rule.priority());
// check if this new rule is an update to an existing entry
for (FlowEntry fe : flowEntries.get(did)) {
if (entry.equals(fe)) {
// TODO update the stats on this flowEntry?
for (FlowRule fe : flowEntries.get(did)) {
if (rule.equals(fe)) {
// TODO update the stats on this FlowRule?
return null;
}
}
flowEntries.put(did, entry);
flowEntries.put(did, rule);
return new FlowRuleEvent(RULE_ADDED, rule);
}
......@@ -77,10 +70,8 @@ public class SimpleFlowRuleStore {
*/
FlowRuleEvent removeFlowRule(FlowRule rule) {
FlowEntry rem = new DefaultFlowEntry(rule.deviceId(),
rule.selector(), rule.treatment(), rule.priority());
synchronized (this) {
if (flowEntries.remove(rem.deviceId(), rem)) {
if (flowEntries.remove(rule.deviceId(), rule)) {
return new FlowRuleEvent(RULE_REMOVED, rule);
} else {
return null;
......
......@@ -21,9 +21,7 @@ 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.FlowRule;
import org.onlab.onos.net.flow.FlowRuleEvent;
import org.onlab.onos.net.flow.FlowRuleListener;
......@@ -91,7 +89,7 @@ public class SimpleFlowRuleManagerTest {
private FlowRule flowRule(int tsval, int trval) {
TestSelector ts = new TestSelector(tsval);
TestTreatment tr = new TestTreatment(trval);
return new DefaultFlowRule(DID, ts, tr);
return new DefaultFlowRule(DID, ts, tr, 0);
}
private void addFlowRule(int hval) {
......@@ -142,14 +140,14 @@ public class SimpleFlowRuleManagerTest {
FlowRule r3 = flowRule(1, 3);
//current FlowRules always return 0. FlowEntries inherit the value
FlowEntry e1 = new DefaultFlowEntry(DID, ts, r1.treatment(), 0);
FlowEntry e2 = new DefaultFlowEntry(DID, ts, r2.treatment(), 0);
FlowEntry e3 = new DefaultFlowEntry(DID, ts, r3.treatment(), 0);
List<FlowEntry> fel = Lists.newArrayList(e1, e2, e3);
FlowRule e1 = new DefaultFlowRule(DID, ts, r1.treatment(), 0);
FlowRule e2 = new DefaultFlowRule(DID, ts, r2.treatment(), 0);
FlowRule e3 = new DefaultFlowRule(DID, ts, r3.treatment(), 0);
List<FlowRule> fel = Lists.newArrayList(e1, e2, e3);
assertTrue("store should be empty",
Sets.newHashSet(service.getFlowEntries(DID)).isEmpty());
List<FlowEntry> ret = mgr.applyFlowRules(r1, r2, r3);
List<FlowRule> ret = mgr.applyFlowRules(r1, r2, r3);
assertEquals("3 rules should exist", 3, flowCount());
assertTrue("3 entries should result", fel.containsAll(ret));
}
......@@ -256,7 +254,7 @@ public class SimpleFlowRuleManagerTest {
}
@Override
public Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId) {
public Iterable<FlowRule> getFlowMetrics(DeviceId deviceId) {
return null;
}
......
......@@ -11,7 +11,6 @@ import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.flow.DefaultFlowRule;
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;
......@@ -96,7 +95,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
@Override
public Iterable<FlowEntry> getFlowMetrics(DeviceId deviceId) {
public Iterable<FlowRule> getFlowMetrics(DeviceId deviceId) {
// TODO Auto-generated method stub
return null;
}
......@@ -133,7 +132,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
case FLOW_REMOVED:
//TODO: make this better
OFFlowRemoved removed = (OFFlowRemoved) msg;
FlowRule fr = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), null, null);
FlowRule fr = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), null, null, 0);
providerService.flowRemoved(fr);
break;
case STATS_REPLY:
......