Change calcPathIntent method to accept IntentOperationList
PathCalcRuntime.calcPathIntent()
- accepts app-level IntentOperationList
- returns PathIntents' IntentOperationList
PathCalcRuntimeModule class
- retains app-level intents and path-level intents
- publishes PathIntents' IntentOperationList
Change-Id: I70576390437f36d8b88849c0098966994b29900d
diff --git a/src/main/java/net/onrc/onos/intent/IntentOperationList.java b/src/main/java/net/onrc/onos/intent/IntentOperationList.java
index 1c916db..af00373 100644
--- a/src/main/java/net/onrc/onos/intent/IntentOperationList.java
+++ b/src/main/java/net/onrc/onos/intent/IntentOperationList.java
@@ -4,4 +4,8 @@
public class IntentOperationList extends ArrayList<IntentOperation> {
private static final long serialVersionUID = -3894081461861052610L;
+
+ public boolean add(IntentOperation.Operator op, Intent intent) {
+ return add(new IntentOperation(op, intent));
+ }
}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/IPathCalcRuntimeService.java b/src/main/java/net/onrc/onos/intent/runtime/IPathCalcRuntimeService.java
new file mode 100644
index 0000000..9e53732
--- /dev/null
+++ b/src/main/java/net/onrc/onos/intent/runtime/IPathCalcRuntimeService.java
@@ -0,0 +1,12 @@
+package net.onrc.onos.intent.runtime;
+
+import net.floodlightcontroller.core.module.IFloodlightService;
+import net.onrc.onos.intent.IntentMap;
+import net.onrc.onos.intent.IntentOperationList;
+
+public interface IPathCalcRuntimeService extends IFloodlightService {
+ public IntentOperationList executeIntentOperations(IntentOperationList list);
+ public IntentMap getHighLevelIntents();
+ public IntentMap getPathIntents();
+ public void purgeIntents();
+}
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntime.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntime.java
index d22d516..32fe746 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntime.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntime.java
@@ -1,11 +1,10 @@
package net.onrc.onos.intent.runtime;
-import java.util.Collection;
+import java.util.HashMap;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.intent.ConstrainedBFSTree;
import net.onrc.onos.intent.ConstrainedShortestPathIntent;
-import net.onrc.onos.intent.Intent;
import net.onrc.onos.intent.IntentOperation;
import net.onrc.onos.intent.IntentOperationList;
import net.onrc.onos.intent.PathIntent;
@@ -24,45 +23,61 @@
this.graph = g;
}
- public PathIntentMap calcPathIntents(Collection<Intent> highLevelIntents, PathIntentMap pathIntents) {
- IntentOperationList intentOpList = new IntentOperationList();
+ /**
+ * calculate shortest-path and constrained-shortest-path intents into low-level path intents
+ * @param intentOpList IntentOperationList having instances of ShortestPathIntent/ConstrainedShortestPathIntent
+ * @param pathIntents a set of current low-level intents
+ * @return IntentOperationList for PathIntent instances
+ */
+ public IntentOperationList calcPathIntents(IntentOperationList intentOpList, PathIntentMap pathIntents) {
+ IntentOperationList pathIntentOpList = new IntentOperationList();
+ HashMap<Switch, ConstrainedBFSTree> spfTrees = new HashMap<>();
- for (Intent intent: highLevelIntents) {
- if (!(intent instanceof ShortestPathIntent)) {
- // unsupported intent type.
- // TODO should push back the intent to caller
- continue;
- }
+ for (IntentOperation intentOp: intentOpList) {
+ switch (intentOp.operator) {
+ case ADD:
+ if (!(intentOp.intent instanceof ShortestPathIntent)) {
+ // unsupported intent type.
+ // TODO should push back the intent to caller
+ continue;
+ }
- ShortestPathIntent spIntent = (ShortestPathIntent) intent;
- Switch srcSwitch = graph.getSwitch(spIntent.getSrcSwitchDpid());
- Switch dstSwitch = graph.getSwitch(spIntent.getDstSwitchDpid());
- if (srcSwitch == null || dstSwitch == null) {
- // incomplete intent.
- // TODO should push back the intent to caller
- continue;
- }
+ ShortestPathIntent spIntent = (ShortestPathIntent) intentOp.intent;
+ Switch srcSwitch = graph.getSwitch(spIntent.getSrcSwitchDpid());
+ Switch dstSwitch = graph.getSwitch(spIntent.getDstSwitchDpid());
+ if (srcSwitch == null || dstSwitch == null) {
+ // incomplete intent.
+ // TODO should push back the intent to caller
+ continue;
+ }
- double bandwidth = 0.0;
- ConstrainedBFSTree tree = null;
- if (intent instanceof ConstrainedShortestPathIntent) {
- bandwidth = ((ConstrainedShortestPathIntent) intent).getBandwidth();
- tree = new ConstrainedBFSTree(srcSwitch, pathIntents, bandwidth);
+ double bandwidth = 0.0;
+ ConstrainedBFSTree tree = null;
+ if (intentOp.intent instanceof ConstrainedShortestPathIntent) {
+ bandwidth = ((ConstrainedShortestPathIntent) intentOp.intent).getBandwidth();
+ tree = new ConstrainedBFSTree(srcSwitch, pathIntents, bandwidth);
+ }
+ else {
+ tree = spfTrees.get(srcSwitch);
+ if (tree == null) {
+ tree = new ConstrainedBFSTree(srcSwitch);
+ spfTrees.put(srcSwitch, tree);
+ }
+ }
+ Path path = tree.getPath(dstSwitch);
+ if (path == null) {
+ // path not found.
+ // TODO should push back the intent to caller
+ continue;
+ }
+ PathIntent pathIntent = new PathIntent("pi" + intentOp.intent.getId(), path, bandwidth, intentOp.intent);
+ pathIntentOpList.add(new IntentOperation(IntentOperation.Operator.ADD, pathIntent));
+ break;
+ case REMOVE:
+ pathIntentOpList.add(intentOp);
+ break;
}
- else {
- tree = new ConstrainedBFSTree(srcSwitch);
- }
- Path path = tree.getPath(dstSwitch);
- if (path == null) {
- // path not found.
- // TODO should push back the intent to caller
- continue;
- }
-
- PathIntent pathIntent = new PathIntent("pi" + intent.getId(), path, bandwidth, intent);
- pathIntents.addIntent(pathIntent);
- intentOpList.add(new IntentOperation(IntentOperation.Operator.ADD, pathIntent));
}
- return pathIntents;
+ return pathIntentOpList;
}
}
\ No newline at end of file
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
index c32b4a7..56758cb 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -14,19 +14,20 @@
import net.onrc.onos.intent.IntentMap;
import net.onrc.onos.intent.IntentOperationList;
import net.onrc.onos.intent.PathIntentMap;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
-public class PathCalcRuntimeModule implements IFloodlightModule {
+public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService {
private PathCalcRuntime runtime;
private IDatagridService datagridService;
- private NetworkGraph networkGraph;
+ private INetworkGraphService networkGraphService;
private IntentMap highLevelIntents;
- private PathIntentMap lowLevelIntents;
-
+ private PathIntentMap pathIntents;
+
private IEventChannel<byte[], IntentOperationList> eventChannel;
private static final String EVENT_CHANNEL_NAME = "onos.pathintent";
-
+
@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
Collection<Class<? extends IFloodlightService>> l = new ArrayList<>(1);
@@ -37,7 +38,7 @@
@Override
public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<>(1);
- m.put(PathCalcRuntime.class, runtime);
+ m.put(IPathCalcRuntimeService.class, this);
return m;
}
@@ -45,16 +46,17 @@
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
Collection<Class<? extends IFloodlightService>> l = new ArrayList<>();
l.add(IDatagridService.class);
+ l.add(INetworkGraphService.class);
return l;
}
@Override
public void init(FloodlightModuleContext context) throws FloodlightModuleException {
datagridService = context.getServiceImpl(IDatagridService.class);
- //networkGraph = new MockNetworkGraph(); // TODO give pointer to the correct NetworkGraph
- runtime = new PathCalcRuntime(networkGraph);
+ networkGraphService = context.getServiceImpl(INetworkGraphService.class);
+ runtime = new PathCalcRuntime(networkGraphService.getNetworkGraph());
highLevelIntents = new IntentMap();
- lowLevelIntents = new PathIntentMap(networkGraph);
+ pathIntents = new PathIntentMap(networkGraphService.getNetworkGraph());
}
@Override
@@ -64,25 +66,33 @@
byte[].class,
IntentOperationList.class);
}
-
- public void executeIntentOperations(IntentOperationList list) {
- highLevelIntents.executeOperations(list);
- lowLevelIntents = runtime.calcPathIntents(
- highLevelIntents.getAllIntents(),
- new PathIntentMap(networkGraph));
- // TODO publishPathIntentOperationList(IntentOperationList list)
- }
-
+
protected void publishPathIntentOperationList(IntentOperationList list) {
eventChannel.addEntry(new byte[1], list); // TODO make key bytes
}
-
- public IntentMap getIntents() {
+
+ @Override
+ public IntentOperationList executeIntentOperations(IntentOperationList list) {
+ highLevelIntents.executeOperations(list);
+ IntentOperationList pathIntentOperations = runtime.calcPathIntents(list, pathIntents);
+ pathIntents.executeOperations(pathIntentOperations);
+ publishPathIntentOperationList(pathIntentOperations);
+ return pathIntentOperations;
+ }
+
+ @Override
+ public IntentMap getHighLevelIntents() {
return highLevelIntents;
}
-
+
+ @Override
+ public IntentMap getPathIntents() {
+ return pathIntents;
+ }
+
+ @Override
public void purgeIntents() {
highLevelIntents.purge();
- lowLevelIntents.purge();
+ pathIntents.purge();
}
}
diff --git a/src/test/java/net/onrc/onos/intent/IntentMapTest.java b/src/test/java/net/onrc/onos/intent/IntentMapTest.java
index ae44e7b..bad546d 100644
--- a/src/test/java/net/onrc/onos/intent/IntentMapTest.java
+++ b/src/test/java/net/onrc/onos/intent/IntentMapTest.java
@@ -1,9 +1,6 @@
package net.onrc.onos.intent;
-import static org.junit.Assert.*;
-
-import java.util.LinkedList;
-
+import static org.junit.Assert.assertEquals;
import net.onrc.onos.intent.Intent.IntentState;
import org.junit.After;
diff --git a/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java b/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
index e32da32..c12a718 100644
--- a/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
+++ b/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
@@ -1,15 +1,22 @@
package net.onrc.onos.intent.runtime;
-import java.util.LinkedList;
-
+import net.floodlightcontroller.core.module.FloodlightModuleContext;
+import net.floodlightcontroller.core.module.FloodlightModuleException;
+import net.onrc.onos.datagrid.IDatagridService;
+import net.onrc.onos.datagrid.IEventChannel;
import net.onrc.onos.intent.ConstrainedShortestPathIntent;
import net.onrc.onos.intent.Intent;
+import net.onrc.onos.intent.IntentOperation.Operator;
+import net.onrc.onos.intent.IntentOperationList;
import net.onrc.onos.intent.MockNetworkGraph;
import net.onrc.onos.intent.PathIntent;
import net.onrc.onos.intent.PathIntentMap;
import net.onrc.onos.intent.ShortestPathIntent;
-import net.onrc.onos.ofcontroller.networkgraph.*;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
+import net.onrc.onos.ofcontroller.networkgraph.Link;
+import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -18,17 +25,46 @@
* @author Toshio Koide (t-koide@onlab.us)
*/
public class UseCaseTest {
- NetworkGraph g;
+ private NetworkGraph g;
+ private FloodlightModuleContext modContext;
+ private IDatagridService datagridService;
+ private INetworkGraphService networkGraphService;
+ @SuppressWarnings("rawtypes")
+ private IEventChannel eventChannel;
+ @SuppressWarnings("unchecked")
@Before
public void setUp() {
MockNetworkGraph graph = new MockNetworkGraph();
graph.createSampleTopology();
g = graph;
+
+ datagridService = EasyMock.createMock(IDatagridService.class);
+ networkGraphService = EasyMock.createMock(INetworkGraphService.class);
+ modContext = EasyMock.createMock(FloodlightModuleContext.class);
+ eventChannel = EasyMock.createMock(IEventChannel.class);
+
+ EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(IDatagridService.class)))
+ .andReturn(datagridService).once();
+ EasyMock.expect(modContext.getServiceImpl(EasyMock.eq(INetworkGraphService.class)))
+ .andReturn(networkGraphService).once();
+
+ networkGraphService.getNetworkGraph();
+ EasyMock.expectLastCall().andReturn(g).anyTimes();
+
+ EasyMock.expect(datagridService.createChannel("onos.pathintent", byte[].class, IntentOperationList.class))
+ .andReturn(eventChannel).once();
+
+ EasyMock.replay(datagridService);
+ EasyMock.replay(networkGraphService);
+ EasyMock.replay(modContext);
}
@After
public void tearDown() {
+ EasyMock.verify(datagridService);
+ EasyMock.verify(networkGraphService);
+ EasyMock.verify(modContext);
}
private void showResult(PathIntentMap intents) {
@@ -47,69 +83,75 @@
}
@Test
- public void useCase1() {
+ public void useCase1() throws FloodlightModuleException {
// create shortest path intents
- LinkedList<Intent> intents = new LinkedList<Intent>();
- intents.add(new ShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 4L));
- intents.add(new ShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 5L));
- intents.add(new ShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 6L));
+ IntentOperationList opList = new IntentOperationList();
+ opList.add(Operator.ADD, new ShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 4L));
+ opList.add(Operator.ADD, new ShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 5L));
+ opList.add(Operator.ADD, new ShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 6L));
- // compile high-level intents into low-level intents (calculate paths)
- PathCalcRuntime runtime1 = new PathCalcRuntime(g);
- PathIntentMap pathIntents = runtime1.calcPathIntents(intents, new PathIntentMap(g));
-
+ // compile high-level intent operations into low-level intent operations (calculate paths)
+ PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
+ runtime1.init(modContext);
+ runtime1.startUp(modContext);
+ IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
+
// compile low-level intents into flow entry installation plan
PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
- runtime2.addIntents(pathIntents);
+ runtime2.addIntents((PathIntentMap) runtime1.getPathIntents()); // TODO use pathIntentOpList
// show results
- showResult(pathIntents);
+ showResult((PathIntentMap) runtime1.getPathIntents());
System.out.println(runtime2.getPlan());
}
@Test
- public void useCase2() {
+ public void useCase2() throws FloodlightModuleException {
// create constrained shortest path intents
- LinkedList<Intent> intents = new LinkedList<Intent>();
- intents.add(new ConstrainedShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 17L, 400.0));
- intents.add(new ConstrainedShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 18L, 400.0));
- intents.add(new ConstrainedShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 19L, 400.0));
- intents.add(new ConstrainedShortestPathIntent("4", 3L, 20L, 4L, 8L, 20L, 20L, 400.0));
- intents.add(new ConstrainedShortestPathIntent("5", 4L, 20L, 5L, 8L, 20L, 21L, 400.0));
+ IntentOperationList opList = new IntentOperationList();
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 17L, 400.0));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 18L, 400.0));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 19L, 400.0));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("4", 3L, 20L, 4L, 8L, 20L, 20L, 400.0));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("5", 4L, 20L, 5L, 8L, 20L, 21L, 400.0));
- // compile high-level intents into low-level intents (calculate paths)
- PathCalcRuntime runtime1 = new PathCalcRuntime(g);
- PathIntentMap pathIntents = runtime1.calcPathIntents(intents, new PathIntentMap(g));
+ // compile high-level intent operations into low-level intent operations (calculate paths)
+ PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
+ runtime1.init(modContext);
+ runtime1.startUp(modContext);
+ IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
// compile low-level intents into flow entry installation plan
PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
- runtime2.addIntents(pathIntents);
+ runtime2.addIntents((PathIntentMap) runtime1.getPathIntents()); // TODO use pathIntentOpList
// show results
- showResult(pathIntents);
+ showResult((PathIntentMap) runtime1.getPathIntents());
System.out.println(runtime2.getPlan());
}
@Test
- public void useCase3() {
+ public void useCase3() throws FloodlightModuleException {
// create constrained & not best effort shortest path intents
- LinkedList<Intent> intents = new LinkedList<Intent>();
- intents.add(new ConstrainedShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 6L, 600.0));
- intents.add(new ConstrainedShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 7L, 600.0));
- intents.add(new ShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 8L));
- intents.add(new ShortestPathIntent("4", 4L, 20L, 4L, 8L, 20L, 9L));
- intents.add(new ConstrainedShortestPathIntent("5", 4L, 20L, 5L, 8L, 20L, 10L, 600.0));
+ IntentOperationList opList = new IntentOperationList();
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("1", 1L, 20L, 1L, 4L, 20L, 6L, 600.0));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("2", 2L, 20L, 2L, 6L, 20L, 7L, 600.0));
+ opList.add(Operator.ADD, new ShortestPathIntent("3", 4L, 20L, 3L, 8L, 20L, 8L));
+ opList.add(Operator.ADD, new ShortestPathIntent("4", 4L, 20L, 4L, 8L, 20L, 9L));
+ opList.add(Operator.ADD, new ConstrainedShortestPathIntent("5", 4L, 20L, 5L, 8L, 20L, 10L, 600.0));
- // compile high-level intents into low-level intents (calculate paths)
- PathCalcRuntime runtime1 = new PathCalcRuntime(g);
- PathIntentMap pathIntents = runtime1.calcPathIntents(intents, new PathIntentMap(g));
+ // compile high-level intent operations into low-level intent operations (calculate paths)
+ PathCalcRuntimeModule runtime1 = new PathCalcRuntimeModule();
+ runtime1.init(modContext);
+ runtime1.startUp(modContext);
+ IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
// compile low-level intents into flow entry installation plan
PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
- runtime2.addIntents(pathIntents);
+ runtime2.addIntents((PathIntentMap) runtime1.getPathIntents()); // TODO use pathIntentOpList
// show results
- showResult(pathIntents);
+ showResult((PathIntentMap) runtime1.getPathIntents());
System.out.println(runtime2.getPlan());
}
}