blob: 3d89e9626ee90a23f3ebb0f51ea62797a5973b04 [file] [log] [blame]
package net.onrc.onos.core.util;
import java.util.ArrayList;
import org.codehaus.jackson.annotate.JsonProperty;
/**
* The data forwarding path state from a source to a destination.
*/
public class DataPath {
private SwitchPort srcPort; // The source port
private SwitchPort dstPort; // The destination port
private ArrayList<FlowEntry> flowEntries; // The Flow Entries
/**
* Default constructor.
*/
public DataPath() {
srcPort = new SwitchPort();
dstPort = new SwitchPort();
flowEntries = new ArrayList<FlowEntry>();
}
/**
* Get the data path source port.
*
* @return the data path source port.
*/
@JsonProperty("srcPort")
public SwitchPort srcPort() {
return srcPort;
}
/**
* Set the data path source port.
*
* @param srcPort the data path source port to set.
*/
@JsonProperty("srcPort")
public void setSrcPort(SwitchPort srcPort) {
this.srcPort = srcPort;
}
/**
* Get the data path destination port.
*
* @return the data path destination port.
*/
@JsonProperty("dstPort")
public SwitchPort dstPort() {
return dstPort;
}
/**
* Set the data path destination port.
*
* @param dstPort the data path destination port to set.
*/
@JsonProperty("dstPort")
public void setDstPort(SwitchPort dstPort) {
this.dstPort = dstPort;
}
/**
* Get the data path flow entries.
*
* @return the data path flow entries.
*/
@JsonProperty("flowEntries")
public ArrayList<FlowEntry> flowEntries() {
return flowEntries;
}
/**
* Set the data path flow entries.
*
* @param flowEntries the data path flow entries to set.
*/
@JsonProperty("flowEntries")
public void setFlowEntries(ArrayList<FlowEntry> flowEntries) {
this.flowEntries = flowEntries;
}
/**
* Apply Flow Path Flags to the pre-computed Data Path.
*
* @param flowPathFlags the Flow Path Flags to apply.
*/
public void applyFlowPathFlags(FlowPathFlags flowPathFlags) {
if (flowPathFlags == null) {
return; // Nothing to do
}
// Discard the first Flow Entry
if (flowPathFlags.isDiscardFirstHopEntry()) {
if (flowEntries.size() > 0) {
flowEntries.remove(0);
}
}
// Keep only the first Flow Entry
if (flowPathFlags.isKeepOnlyFirstHopEntry()) {
if (flowEntries.size() > 1) {
FlowEntry flowEntry = flowEntries.get(0);
flowEntries.clear();
flowEntries.add(flowEntry);
}
}
}
/**
* Remove Flow Entries that were deleted.
*/
public void removeDeletedFlowEntries() {
//
// NOTE: We create a new ArrayList, and add only the Flow Entries
// that are NOT FE_USER_DELETE.
// This is sub-optimal: if it adds notable processing cost,
// the Flow Entries container should be changed to LinkedList
// or some other container that has O(1) cost of removing an entry.
//
// Test first whether any Flow Entry was deleted
boolean foundDeletedFlowEntry = false;
for (FlowEntry flowEntry : this.flowEntries) {
if (flowEntry.flowEntryUserState() ==
FlowEntryUserState.FE_USER_DELETE) {
foundDeletedFlowEntry = true;
break;
}
}
if (!foundDeletedFlowEntry) {
return; // Nothing to do
}
// Create a new collection and exclude the deleted flow entries
ArrayList<FlowEntry> newFlowEntries = new ArrayList<FlowEntry>();
for (FlowEntry flowEntry : this.flowEntries()) {
if (flowEntry.flowEntryUserState() !=
FlowEntryUserState.FE_USER_DELETE) {
newFlowEntries.add(flowEntry);
}
}
setFlowEntries(newFlowEntries);
}
/**
* Convert the data path to a string.
* <p/>
* The string has the following form:
* [src=01:01:01:01:01:01:01:01/1111 flowEntry=<entry1> flowEntry=<entry2>
* flowEntry=<entry3> dst=02:02:02:02:02:02:02:02/2222]
*
* @return the data path as a string.
*/
@Override
public String toString() {
StringBuilder ret = new StringBuilder();
ret.append("[src=" + this.srcPort.toString());
for (FlowEntry fe : flowEntries) {
ret.append(" flowEntry=" + fe.toString());
}
ret.append(" dst=" + this.dstPort.toString() + "]");
return ret.toString();
}
}