Implement rerouting feature in PathCalcRuntimeModule

Change-Id: Ie37ebd1fa6910e999d457481d7082adb0d1d9a3a
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 26afe51..d72a13a 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PathCalcRuntimeModule.java
@@ -11,22 +11,43 @@
 import net.floodlightcontroller.core.module.IFloodlightService;
 import net.onrc.onos.datagrid.IDatagridService;
 import net.onrc.onos.datagrid.IEventChannel;
+import net.onrc.onos.intent.Intent;
 import net.onrc.onos.intent.IntentMap;
+import net.onrc.onos.intent.IntentOperation.Operator;
 import net.onrc.onos.intent.IntentOperationList;
+import net.onrc.onos.intent.PathIntent;
 import net.onrc.onos.intent.PathIntentMap;
+import net.onrc.onos.ofcontroller.networkgraph.DeviceEvent;
+import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphListener;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
-import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+import net.onrc.onos.ofcontroller.networkgraph.PortEvent;
+import net.onrc.onos.ofcontroller.networkgraph.SwitchEvent;
 
-public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService {
+/**
+ * @author Toshio Koide (t-koide@onlab.us)
+ */
+public class PathCalcRuntimeModule implements IFloodlightModule, IPathCalcRuntimeService, INetworkGraphListener {
 	private PathCalcRuntime runtime;
 	private IDatagridService datagridService;
 	private INetworkGraphService networkGraphService;
 	private IntentMap highLevelIntents;
 	private PathIntentMap pathIntents;
 
-	private IEventChannel<byte[], IntentOperationList> eventChannel;
+	private IEventChannel<String, IntentOperationList> eventChannel;
 	private static final String EVENT_CHANNEL_NAME = "onos.pathintent";
 
+	private void reroutePaths(LinkEvent linkEvent) {
+		Collection<PathIntent> oldPaths = pathIntents.getIntentsByLink(linkEvent);
+		if (oldPaths == null) return;
+		IntentOperationList reroutingOperation = new IntentOperationList();
+		for (PathIntent pathIntent: oldPaths) {
+			// TODO use Operator.UPDATE instead of REMOVE and ADD in order to optimize
+			reroutingOperation.add(Operator.REMOVE, new Intent(pathIntent.getParentIntent().getId()));
+			reroutingOperation.add(Operator.ADD, pathIntent.getParentIntent());
+		}
+		executeIntentOperations(reroutingOperation);
+	}
 
 	@Override
 	public Collection<Class<? extends IFloodlightService>> getModuleServices() {
@@ -60,23 +81,22 @@
 	public void startUp(FloodlightModuleContext context) {
 		highLevelIntents = new IntentMap();
 		runtime = new PathCalcRuntime(networkGraphService.getNetworkGraph());
-		pathIntents = new PathIntentMap(networkGraphService.getNetworkGraph());
+		pathIntents = new PathIntentMap();
 		eventChannel = datagridService.createChannel(
 				EVENT_CHANNEL_NAME,
-				byte[].class,
+				String.class,
 				IntentOperationList.class);
-	}
-
-	protected void publishPathIntentOperationList(IntentOperationList list) {
-		eventChannel.addEntry(new byte[1], list); // TODO make key bytes		
+		networkGraphService.registerNetworkGraphListener(this);
 	}
 
 	@Override
 	public IntentOperationList executeIntentOperations(IntentOperationList list) {
 		highLevelIntents.executeOperations(list);
 		IntentOperationList pathIntentOperations = runtime.calcPathIntents(list, pathIntents);
+		String key = "..."; // TODO generate key
+		System.out.println(pathIntentOperations);
 		pathIntents.executeOperations(pathIntentOperations);
-		publishPathIntentOperationList(pathIntentOperations);
+		eventChannel.addEntry(key, pathIntentOperations);
 		return pathIntentOperations;
 	}
 
@@ -95,4 +115,44 @@
 		highLevelIntents.purge();
 		pathIntents.purge();
 	}
+
+	@Override
+	public void putSwitchEvent(SwitchEvent switchEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void removeSwitchEvent(SwitchEvent switchEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void putPortEvent(PortEvent portEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void removePortEvent(PortEvent portEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void putLinkEvent(LinkEvent linkEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void removeLinkEvent(LinkEvent linkEvent) {
+		reroutePaths(linkEvent);
+	}
+
+	@Override
+	public void putDeviceEvent(DeviceEvent deviceEvent) {
+		// do nothing
+	}
+
+	@Override
+	public void removeDeviceEvent(DeviceEvent deviceEvent) {
+		// do nothing
+	}
 }