Implement compile method for PacketPathFlow class.
- This patch supports ADD operation only.
- This task is a part of ONOS-1741 and ONOS-1690.
Change-Id: Idd1cad5cf582df77633dae45b1fd5a9756708134
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
index ce1fdb4..42cbd65 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
@@ -1,16 +1,24 @@
package net.onrc.onos.api.flowmanager;
import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedList;
import java.util.List;
import net.onrc.onos.api.flowmanager.FlowBatchOperation.Operator;
+import net.onrc.onos.core.matchaction.MatchAction;
import net.onrc.onos.core.matchaction.MatchActionIdGenerator;
+import net.onrc.onos.core.matchaction.MatchActionOperationEntry;
import net.onrc.onos.core.matchaction.MatchActionOperations;
import net.onrc.onos.core.matchaction.MatchActionOperationsIdGenerator;
import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.action.OutputAction;
import net.onrc.onos.core.matchaction.match.PacketMatch;
import net.onrc.onos.core.util.PortNumber;
+import net.onrc.onos.core.util.SwitchPort;
/**
* Flow object representing a packet path.
@@ -70,7 +78,105 @@
public List<MatchActionOperations> compile(Operator op,
MatchActionIdGenerator maIdGenerator,
MatchActionOperationsIdGenerator maoIdGenerator) {
- // TODO Auto-generated method stub
- return null;
+ switch (op) {
+ case ADD:
+ return compileAddOperation(maIdGenerator, maoIdGenerator);
+ case REMOVE:
+ return compileRemoveOperation(maIdGenerator, maoIdGenerator);
+ default:
+ throw new UnsupportedOperationException("Unknown operation.");
+ }
+ }
+
+ /**
+ * Creates the next {@link MatchAction} object using iterators.
+ *
+ * @param portIterator the iterator for {@link SwitchPort} objects
+ * @param actionsIterator the iterator for the lists of {@link Action}
+ * @param maIdGenerator the ID generator of {@link MatchAction}
+ * @return {@link MatchAction} object based on the specified iterators
+ */
+ private MatchAction createNextMatchAction(Iterator<SwitchPort> portIterator,
+ Iterator<List<Action>> actionsIterator,
+ MatchActionIdGenerator maIdGenerator) {
+ if (portIterator == null || actionsIterator == null ||
+ !portIterator.hasNext() || !actionsIterator.hasNext()) {
+ return null;
+ }
+
+ // TODO: Update this after merging the new MatchAction API.
+ return new MatchAction(
+ maIdGenerator.getNewId(),
+ portIterator.next(),
+ getMatch(), actionsIterator.next());
+ }
+
+ /**
+ * Generates the list of {@link MatchActionOperations} objects with
+ * add-operation.
+ *
+ * @return the list of {@link MatchActionOperations} objects
+ */
+ private List<MatchActionOperations> compileAddOperation(
+ MatchActionIdGenerator maIdGenerator,
+ MatchActionOperationsIdGenerator maoIdGenerator) {
+ Path path = checkNotNull(getPath());
+ checkState(path.size() > 0, "Path object has no link.");
+
+ // Preparing each actions and ingress port for each switch
+ List<List<Action>> actionsList = new LinkedList<>();
+ List<SwitchPort> portList = new LinkedList<>();
+ for (FlowLink link : path) {
+ portList.add(link.getDstSwitchPort());
+ actionsList.add(Arrays.asList(
+ (Action) new OutputAction(link.getSrcPortNumber())));
+ }
+
+ // The head switch's ingress port
+ portList.add(0, new SwitchPort(path.getSrcDpid(), getIngressPortNumber()));
+
+ // The tail switch's action
+ actionsList.add(getEgressActions());
+
+ Iterator<SwitchPort> portIterator = portList.iterator();
+ Iterator<List<Action>> actionsIterator = actionsList.iterator();
+
+ // Creates the second phase operation
+ // using the head switch's match action
+ MatchAction headMatchAction = createNextMatchAction(portIterator,
+ actionsIterator, maIdGenerator);
+ if (headMatchAction == null) {
+ return null;
+ }
+ MatchActionOperations secondOp = new MatchActionOperations(
+ maoIdGenerator.getNewId());
+ secondOp.addOperation(new MatchActionOperationEntry(
+ MatchActionOperations.Operator.ADD, headMatchAction));
+
+ // Creates the first phase operation
+ // using the remaining switches' match actions
+ MatchActionOperations firstOp = new MatchActionOperations(
+ maoIdGenerator.getNewId());
+ MatchAction ma;
+ while ((ma = createNextMatchAction(portIterator, actionsIterator, maIdGenerator)) != null) {
+ firstOp.addOperation(new MatchActionOperationEntry(
+ MatchActionOperations.Operator.ADD, ma));
+ }
+
+ return Arrays.asList(firstOp, secondOp);
+ }
+
+ /**
+ * Generates the list of {@link MatchActionOperations} objects with
+ * remote-operation.
+ *
+ * @return the list of {@link MatchActionOperations} objects
+ */
+ private List<MatchActionOperations> compileRemoveOperation(
+ MatchActionIdGenerator maIdGenerator,
+ MatchActionOperationsIdGenerator maoIdGenerator) {
+ // TODO implement it
+ throw new UnsupportedOperationException(
+ "REMOVE operation is not implemented yet.");
}
}