Update the Flow classes.
- Changed all Flow classes to use FlowId object on its constructor for their ID.
- Implement equals() and hashCode() for all Flow classes based on FlowId.
- Changed SingleDstTreeFlow class to accept the list of Action objects on its constructor.
- Updated the Tree class's constructor to accept the list of links.
- This task is a part of ONOS-1841, ONOS-1694, ONOS-1741.
Change-Id: I930007ce7f92b5bbde4efef9eb9ab893c356abf1
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/Flow.java b/src/main/java/net/onrc/onos/api/flowmanager/Flow.java
index 0622be6..8fe9577 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/Flow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/Flow.java
@@ -1,37 +1,83 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
import net.onrc.onos.api.batchoperation.BatchOperationTarget;
import net.onrc.onos.core.matchaction.MatchActionOperations;
import net.onrc.onos.core.matchaction.match.Match;
/**
- * An interface class to define flow object which is managed by
+ * An abstract class to define flow object which is managed by
* FlowManagerModule.
- * <p>
- * The flow objects (eg. path, tree, disjoint-paths, etc.) must implement this
- * interface.
*/
-public interface Flow extends BatchOperationTarget {
+public abstract class Flow implements BatchOperationTarget {
+ private final FlowId id;
+
+ /**
+ * Creates Flow object using specified ID.
+ *
+ * @param id the ID to be assigned
+ */
+ public Flow(FlowId id) {
+ this.id = checkNotNull(id);
+ }
+
/**
* Gets ID for this flow object.
*
- * @return ID for this object.
+ * @return ID for this object
*/
- public FlowId getId();
+ public FlowId getId() {
+ return id;
+ }
/**
* Gets traffic filter for this flow object.
*
- * @return a traffic filter for this flow object.
+ * @return a traffic filter for this flow object
*/
- public Match getMatch();
+ public abstract Match getMatch();
/**
- * Compiles this object to MatchAction plan.
+ * Compiles this object to MatchAction operations.
* <p>
* This method is called by FlowManagerModule to create MatchAction operations.
*
- * @return a MatchAction plan of this flow object.
+ * @return a MatchActionOperations of this flow object
*/
- public MatchActionOperations compile();
+ public abstract MatchActionOperations compile();
+
+ /**
+ * Generates a hash code using the FlowId.
+ *
+ * @return hashcode
+ */
+ @Override
+ public int hashCode() {
+ return (id == null) ? 0 : id.hashCode();
+ }
+
+ /**
+ * Compares two flow objects by type (class) and FlowId.
+ *
+ * @param obj other Flow object
+ * @return true if equal, false otherwise
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if ((obj == null) || !(obj instanceof Flow)) {
+ return false;
+ }
+ Flow other = (Flow) obj;
+ if (id == null) {
+ if (other.id != null) {
+ return false;
+ }
+ } else if (!id.equals(other.id)) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/OpticalPathFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/OpticalPathFlow.java
index 64b7e2e..4018a7c 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/OpticalPathFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/OpticalPathFlow.java
@@ -4,6 +4,8 @@
import net.onrc.onos.core.matchaction.MatchActionOperations;
import net.onrc.onos.core.matchaction.action.Action;
+import net.onrc.onos.core.matchaction.match.PacketMatch;
+import net.onrc.onos.core.matchaction.match.PacketMatchBuilder;
import net.onrc.onos.core.util.PortNumber;
/**
@@ -11,30 +13,42 @@
* <p>
* TODO: Think this: How do we deal the optical path flow going through the
* regenerators? Can we express it with multiple OpticalPathFlow objects?
+ * <p>
+ * NOTE: This class is not fully supported for the August release.
*/
public class OpticalPathFlow extends PathFlow {
- protected int lambda;
+ private final int lambda;
/**
* Constructor.
*
- * @param id ID for this new Flow object.
- * @param inPort Ingress port number at the ingress edge node.
- * @param path Path between ingress and egress edge node.
- * @param actions The list of Action objects at the egress edge node.
- * @param lambda The lambda to be used throughout the path.
+ * @param id the ID for this new Flow object
+ * @param ingressPort the Ingress port number at the ingress edge node
+ * @param path the Path between ingress and egress edge node
+ * @param egressActions the list of Action objects at the egress edge node
+ * @param lambda the lambda to be used throughout the path
*/
- public OpticalPathFlow(String id,
- PortNumber inPort, Path path, List<Action> actions, int lambda) {
- super(id, null, inPort, path, actions);
+ public OpticalPathFlow(FlowId id,
+ PortNumber ingressPort, Path path, List<Action> egressActions, int lambda) {
+ super(id, ingressPort, path, egressActions);
this.lambda = lambda;
- // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Gets traffic filter for this flow.
+ * <p>
+ * This method only returns wildcard match, because the ingress transponder
+ * port does not have filtering functionality.
+ */
+ @Override
+ public PacketMatch getMatch() {
+ return (new PacketMatchBuilder()).build();
}
/**
* Gets lambda which is used throughout the path.
*
- * @return lambda which is used throughout the path.
+ * @return lambda which is used throughout the path
*/
public int getLambda() {
return lambda;
@@ -43,6 +57,6 @@
@Override
public MatchActionOperations compile() {
// TODO Auto-generated method stub
- return super.compile();
+ return null;
}
}
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 040b9a7..8a15f3f 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/PacketPathFlow.java
@@ -1,5 +1,7 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.List;
import net.onrc.onos.core.matchaction.MatchActionOperations;
@@ -13,28 +15,36 @@
* TODO: Think this: Do we need a bandwidth constraint?
*/
public class PacketPathFlow extends PathFlow {
- private int hardTimeout;
- private int idleTimeout;
+ private final PacketMatch match;
+ private final int hardTimeout;
+ private final int idleTimeout;
/**
* Constructor.
*
- * @param id ID for this new Flow object.
- * @param match Match object at the source node of the path.
- * @param inPort Ingress port number at the ingress edge node.
- * @param path Path between ingress and egress edge node.
- * @param edgeActions The list of Action objects at the egress edge node.
- * @param hardTimeout hard-timeout value.
- * @param idleTimeout idle-timeout value.
+ * @param id ID for this new Flow object
+ * @param match the Match object at the source node of the path
+ * @param ingressPort the Ingress port number at the ingress edge node
+ * @param path the Path between ingress and egress edge node
+ * @param egressActions the list of Action objects at the egress edge node
+ * @param hardTimeout the hard-timeout value in seconds, or 0 for no timeout
+ * @param idleTimeout the idle-timeout value in seconds, or 0 for no timeout
*/
- public PacketPathFlow(String id,
- PacketMatch match, PortNumber inPort, Path path, List<Action> edgeActions,
+ public PacketPathFlow(FlowId id,
+ PacketMatch match, PortNumber ingressPort, Path path,
+ List<Action> egressActions,
int hardTimeout, int idleTimeout) {
- super(id, match, inPort, path, edgeActions);
+ super(id, ingressPort, path, egressActions);
+ this.match = checkNotNull(match);
this.hardTimeout = hardTimeout;
this.idleTimeout = idleTimeout;
}
+ @Override
+ public PacketMatch getMatch() {
+ return match;
+ }
+
/**
* Gets idle-timeout value.
*
@@ -56,6 +66,6 @@
@Override
public MatchActionOperations compile() {
// TODO Auto-generated method stub
- return super.compile();
+ return null;
}
}
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/Path.java b/src/main/java/net/onrc/onos/api/flowmanager/Path.java
index df61e51..2f733a4 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/Path.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/Path.java
@@ -1,5 +1,7 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@@ -18,6 +20,35 @@
}
/**
+ * Constructor to create the object from the list of FlowLinks.
+ *
+ * @param links the list of FlowLinks
+ * @throws IllegalArgumentException if the links does not form a single
+ * connected directed path topology
+ */
+ public Path(List<FlowLink> links) {
+ super();
+ checkNotNull(links);
+ for (FlowLink link : links) {
+ if (!addLink(link)) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ /**
+ * Adds FlowLink to the Path object.
+ *
+ * @param link the FlowLink object to be added
+ * @return true if succeeded, false otherwise
+ */
+ public boolean addLink(FlowLink link) {
+ // TODO check connectivity
+ checkNotNull(link);
+ return add(link);
+ }
+
+ /**
* Gets a list of switch DPIDs of the path.
*
* @return a list of Dpid objects
@@ -29,7 +60,7 @@
List<Dpid> dpids = new ArrayList<Dpid>(size() + 1);
dpids.add(getSrcDpid());
- for (FlowLink link: this) {
+ for (FlowLink link : this) {
dpids.add(link.getDstDpid());
}
return dpids;
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/PathFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/PathFlow.java
index d1b10f6..0cc35ce 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/PathFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/PathFlow.java
@@ -1,64 +1,41 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.List;
-import net.onrc.onos.core.matchaction.MatchActionOperations;
import net.onrc.onos.core.matchaction.action.Action;
-import net.onrc.onos.core.matchaction.match.Match;
import net.onrc.onos.core.util.PortNumber;
/**
- * A path flow.
- * <p>
- * TODO: Think this: Should this class be an abstract class? Is it enough to
- * have only the PacketPathFlow and OpticalPathFlow classes?
+ * An abstract class expressing a path flow.
*/
-public class PathFlow implements Flow {
- protected final FlowId id;
- protected Match match;
- protected PortNumber ingressPort;
- protected Path path;
- protected List<Action> egressActions;
+public abstract class PathFlow extends Flow {
+ private final PortNumber ingressPort;
+ private final Path path;
+ private final List<Action> egressActions;
/**
- * Constructor.
+ * Creates the new flow instance.
*
- * @param id ID for this new PathFlow object.
- * @param match Match object at the ingress node of the path.
- * @param ingressPort The ingress port number at the ingress node of the
- * path.
- * @param path Path between ingress and egress edge node.
- * @param egressActions The list of Action objects at the egress edge node.
+ * @param id ID for this new PathFlow object
+ * @param ingressPort the ingress port number at the ingress node of the
+ * path
+ * @param path the Path between ingress and egress edge node
+ * @param egressActions the list of Action objects at the egress edge node
*/
- public PathFlow(String id,
- Match match, PortNumber ingressPort, Path path, List<Action> egressActions) {
- this.id = new FlowId(id);
- this.match = match;
- this.ingressPort = ingressPort;
- this.path = path;
- this.egressActions = egressActions;
- }
-
- @Override
- public FlowId getId() {
- return id;
- }
-
- @Override
- public Match getMatch() {
- return match;
- }
-
- @Override
- public MatchActionOperations compile() {
- // TODO Auto-generated method stub
- return null;
+ public PathFlow(FlowId id,
+ PortNumber ingressPort, Path path, List<Action> egressActions) {
+ super(id);
+ this.ingressPort = checkNotNull(ingressPort);
+ this.path = checkNotNull(path);
+ this.egressActions = checkNotNull(egressActions);
}
/**
* Gets the ingress port number at the ingress node of the path.
*
- * @return The ingress port number at the ingress node of the path.
+ * @return the ingress port number at the ingress node of the path
*/
public PortNumber getIngressPortNumber() {
return ingressPort;
@@ -67,7 +44,7 @@
/**
* Gets the path from ingress to egress edge node.
*
- * @return The path object from ingress to egress edge node.
+ * @return the path object from ingress to egress edge node
*/
public Path getPath() {
return path;
@@ -76,7 +53,7 @@
/**
* Gets the list of Action objects at the egress edge node.
*
- * @return The list of Action objects at the egress edge node.
+ * @return the list of Action objects at the egress edge node
*/
public List<Action> getEgressActions() {
return egressActions;
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/SingleDstTreeFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/SingleDstTreeFlow.java
index af403ed..92533cb 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/SingleDstTreeFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/SingleDstTreeFlow.java
@@ -1,15 +1,19 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import net.onrc.onos.core.matchaction.MatchActionOperations;
-import net.onrc.onos.core.matchaction.action.OutputAction;
+import net.onrc.onos.core.matchaction.action.Action;
import net.onrc.onos.core.matchaction.match.PacketMatch;
import net.onrc.onos.core.util.SwitchPort;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
/**
* A Flow object expressing the multipoints-to-point tree flow for the packet
* layer.
@@ -17,37 +21,36 @@
* NOTE: This class might generate the MatchActionPlan which includes the MAC
* address modifications or other the label-switching-like schemes.
*/
-public class SingleDstTreeFlow implements Flow {
- protected final FlowId id;
- protected PacketMatch match;
- protected Set<SwitchPort> ingressPorts;
- protected Tree tree;
- protected OutputAction outputAction;
+public class SingleDstTreeFlow extends Flow {
+ private final PacketMatch match;
+ private final Set<SwitchPort> ingressPorts;
+ private final Tree tree;
+ private final List<Action> actions;
/**
* Creates new instance using Tree object.
+ * <p>
+ * For now, the actions parameter must be the list of a single
+ * ModifyDstMacAction object and a single OutputAction object. But in the
+ * future, the parameter should accept any type of the list of IAction
+ * objects.
*
- * @param id ID for this object.
- * @param match Traffic filter for the tree.
- * @param ingressPorts A set of ingress ports of the tree.
- * @param tree Tree object specifying tree topology for this object.
- * @param outputAction OutputAction object at the egress edge switch.
+ * @param id ID for this object
+ * @param match the traffic filter for the tree
+ * @param ingressPorts the set of ingress ports of the tree
+ * @param tree the Tree object specifying tree topology for this object
+ * @param actions the list of Action objects at the egress edge switch
*/
- public SingleDstTreeFlow(String id, PacketMatch match,
- Collection<SwitchPort> ingressPorts, Tree tree, OutputAction outputAction) {
- this.id = new FlowId(id);
- this.match = match;
- this.ingressPorts = new HashSet<SwitchPort>(ingressPorts);
- this.tree = tree;
- this.outputAction = outputAction;
+ public SingleDstTreeFlow(FlowId id, PacketMatch match,
+ Collection<SwitchPort> ingressPorts, Tree tree, List<Action> actions) {
+ super(id);
+ this.match = checkNotNull(match);
+ this.ingressPorts = ImmutableSet.copyOf(checkNotNull(ingressPorts));
+ this.tree = checkNotNull(tree);
+ this.actions = ImmutableList.copyOf(checkNotNull(actions));
// TODO: check if the tree is a MP2P tree.
- // TODO: check consistency among inPorts, tree, and action.
- }
-
- @Override
- public FlowId getId() {
- return id;
+ // TODO: check consistency among ingressPorts, tree, and actions.
}
@Override
@@ -64,27 +67,27 @@
/**
* Gets the ingress ports of the tree.
*
- * @return The ingress ports of the tree.
+ * @return the ingress ports of the tree
*/
public Collection<SwitchPort> getIngressPorts() {
- return Collections.unmodifiableCollection(ingressPorts);
+ return ingressPorts;
}
/**
* Gets the tree.
*
- * @return The tree object.
+ * @return the tree object
*/
public Tree getTree() {
return tree;
}
/**
- * Gets the output action for the tree.
+ * Gets the list of actions at the egress edge switch.
*
- * @return The OutputAction object.
+ * @return the list of actions at the egress edge switch
*/
- public OutputAction getOutputAction() {
- return outputAction;
+ public List<Action> getEgressActions() {
+ return actions;
}
}
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java b/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
index 7430b7f..bb896c8 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/SingleSrcTreeFlow.java
@@ -1,5 +1,7 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.Set;
import net.onrc.onos.core.matchaction.MatchActionOperations;
@@ -12,9 +14,10 @@
/**
* A Flow object expressing the point-to-multipoints tree flow for the packet
* layer.
+ * <p>
+ * NOTE: This class is not fully supported for the August release.
*/
-public class SingleSrcTreeFlow implements Flow {
- protected final FlowId id;
+public class SingleSrcTreeFlow extends Flow {
protected PacketMatch match;
protected SwitchPort ingressPort;
protected Tree tree;
@@ -23,31 +26,26 @@
/**
* Creates new instance using Tree object.
*
- * @param id ID for this object.
- * @param match Traffic filter for the tree.
- * @param ingressPort A ingress port of the tree.
- * @param tree Tree object specifying tree topology for this object.
- * @param outputActions The set of the pairs of the switch DPID and
- * OutputAction object at the egress edge switchs.
+ * @param id ID for this object
+ * @param match the traffic filter for the tree
+ * @param ingressPort an ingress port of the tree
+ * @param tree the tree object specifying tree topology for this object
+ * @param outputActions the set of the pairs of the switch DPID and
+ * OutputAction object at the egress edge switchs
*/
- public SingleSrcTreeFlow(String id, PacketMatch match,
+ public SingleSrcTreeFlow(FlowId id, PacketMatch match,
SwitchPort ingressPort, Tree tree, Set<Pair<Dpid, OutputAction>> outputActions) {
- this.id = new FlowId(id);
- this.match = match;
- this.ingressPort = ingressPort;
- this.tree = tree;
- this.outputActions = outputActions;
+ super(id);
+ this.match = checkNotNull(match);
+ this.ingressPort = checkNotNull(ingressPort);
+ this.tree = checkNotNull(tree);
+ this.outputActions = checkNotNull(outputActions);
// TODO: check if the tree is a P2MP tree.
// TODO: check consistency among rootPort, tree, and actions.
}
@Override
- public FlowId getId() {
- return id;
- }
-
- @Override
public PacketMatch getMatch() {
return match;
}
diff --git a/src/main/java/net/onrc/onos/api/flowmanager/Tree.java b/src/main/java/net/onrc/onos/api/flowmanager/Tree.java
index 49b05dc..1e161a2 100644
--- a/src/main/java/net/onrc/onos/api/flowmanager/Tree.java
+++ b/src/main/java/net/onrc/onos/api/flowmanager/Tree.java
@@ -1,5 +1,7 @@
package net.onrc.onos.api.flowmanager;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
@@ -25,14 +27,43 @@
}
/**
- * Creates new instance using Path object.
+ * Creates new instance from the specified Path object.
+ *
+ * @param path the Path object
+ * @throws IllegalArgumentException if the path object does not form a
+ * single connected directed path topology
*/
public Tree(Path path) {
super();
- // TODO implement
+ checkNotNull(path);
+
+ for (FlowLink link : path) {
+ if (!addLink(link)) {
+ throw new IllegalArgumentException();
+ }
+ }
+ }
+
+ /**
+ * Creates new instance using FlowLinks object.
+ *
+ * @param links the FlowLinks object
+ * @throws IllegalArgumentException if the links object does not form a
+ * single connected directed tree topology
+ */
+ public Tree(FlowLinks links) {
+ super();
+ checkNotNull(links);
+
+ for (FlowLink link : links) {
+ if (!addLink(link)) {
+ throw new IllegalArgumentException();
+ }
+ }
}
private void addPort(SwitchPort port) {
+ checkNotNull(port);
if (!ports.containsKey(port.dpid())) {
ports.put(port.dpid(), new HashSet<PortNumber>());
}
@@ -49,6 +80,7 @@
* @return true if succeeded, false otherwise.
*/
public boolean addLink(FlowLink link) {
+ checkNotNull(link);
if (links.size() > 0) {
if (!hasDpid(link.getSrcDpid()) && !hasDpid(link.getDstDpid())) {
// no attaching point
diff --git a/src/main/java/net/onrc/onos/core/newintent/PathFlowIntent.java b/src/main/java/net/onrc/onos/core/newintent/PathFlowIntent.java
index 988a8b3..39a1898 100644
--- a/src/main/java/net/onrc/onos/core/newintent/PathFlowIntent.java
+++ b/src/main/java/net/onrc/onos/core/newintent/PathFlowIntent.java
@@ -1,33 +1,33 @@
package net.onrc.onos.core.newintent;
-import com.google.common.base.Objects;
-import net.onrc.onos.api.flowmanager.PathFlow;
+import static com.google.common.base.Preconditions.checkNotNull;
+import net.onrc.onos.api.flowmanager.PacketPathFlow;
import net.onrc.onos.api.newintent.AbstractIntent;
import net.onrc.onos.api.newintent.InstallableIntent;
import net.onrc.onos.api.newintent.IntentId;
-import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Objects;
/**
- * Intent containing {@link PathFlow} object, which defines an explicit path.
+ * Intent containing {@link PacketPathFlow} object, which defines an explicit path.
*
* It is intended to establish a path by using Flow Manager's API.
*/
public class PathFlowIntent extends AbstractIntent implements InstallableIntent {
- private final PathFlow flow;
+ private final PacketPathFlow flow;
- public PathFlowIntent(IntentId id, PathFlow flow) {
+ public PathFlowIntent(IntentId id, PacketPathFlow flow) {
super(id);
this.flow = checkNotNull(flow);
}
/**
- * Returns {@link PathFlow} object, which defines an explicit path.
+ * Returns {@link PacketPathFlow} object, which defines an explicit path.
*
- * @return {@link PathFlow path}
+ * @return {@link PacketPathFlow path}
*/
- public PathFlow getFlow() {
+ public PacketPathFlow getFlow() {
return flow;
}