| 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(); |
| } |
| } |