Intents: Converted Switch/Port objects to longs for Plan calc

Also, added notification once flows are received and installed

Change-Id: I13f8d9de9dcbf9eff584532e1bf901e78a8dc53f
diff --git a/src/main/java/net/onrc/onos/intent/FlowEntry.java b/src/main/java/net/onrc/onos/intent/FlowEntry.java
index 13bfa21..374e5d6 100644
--- a/src/main/java/net/onrc/onos/intent/FlowEntry.java
+++ b/src/main/java/net/onrc/onos/intent/FlowEntry.java
@@ -5,8 +5,6 @@
 
 import net.floodlightcontroller.util.MACAddress;
 import net.onrc.onos.intent.IntentOperation.Operator;
-import net.onrc.onos.ofcontroller.networkgraph.Port;
-import net.onrc.onos.ofcontroller.networkgraph.Switch;
 import net.onrc.onos.ofcontroller.util.Dpid;
 import net.onrc.onos.ofcontroller.util.FlowEntryActions;
 import net.onrc.onos.ofcontroller.util.FlowEntryId;
@@ -19,12 +17,12 @@
  */
 
 public class FlowEntry {
-	protected Switch sw;
+	protected long sw;
 	protected Match match;
 	protected Set<Action> actions;
 	protected Operator operator;
 	
-	public FlowEntry(Switch sw, Port srcPort, Port dstPort, 
+	public FlowEntry(long sw, long srcPort, long dstPort, 
 			 MACAddress srcMac, MACAddress dstMac,
 			 Operator operator) {
 		this.sw = sw;
@@ -38,7 +36,7 @@
 		return match + "->" + actions;
 	}
 	
-	public Switch getSwitch() {
+	public long getSwitch() {
 	    return sw;
 	}
 	
@@ -52,7 +50,7 @@
 	
 	public net.onrc.onos.ofcontroller.util.FlowEntry getFlowEntry() {
 		net.onrc.onos.ofcontroller.util.FlowEntry entry = new net.onrc.onos.ofcontroller.util.FlowEntry();
-		entry.setDpid(new Dpid(sw.getDpid()));
+		entry.setDpid(new Dpid(sw));
 		entry.setFlowEntryId(new FlowEntryId(0)); // all zero for now
 		entry.setFlowEntryMatch(match.getFlowEntryMatch());
 		FlowEntryActions flowEntryActions = new FlowEntryActions();
@@ -67,6 +65,8 @@
 		case REMOVE:
 		    entry.setFlowEntryUserState(FlowEntryUserState.FE_USER_DELETE);
 		    break;
+		default:
+		    break;
 		}
 		return entry;
 	}
diff --git a/src/main/java/net/onrc/onos/intent/ForwardAction.java b/src/main/java/net/onrc/onos/intent/ForwardAction.java
index c6769b8..6ca514d 100644
--- a/src/main/java/net/onrc/onos/intent/ForwardAction.java
+++ b/src/main/java/net/onrc/onos/intent/ForwardAction.java
@@ -1,6 +1,5 @@
 package net.onrc.onos.intent;
 
-import net.onrc.onos.ofcontroller.networkgraph.Port;
 import net.onrc.onos.ofcontroller.util.FlowEntryAction;
 
 /**
@@ -10,20 +9,20 @@
  */
 
 class ForwardAction extends Action {
-	protected Port dstPort;
+	protected long dstPort;
 	
-	public ForwardAction(Port dstPort) {
+	public ForwardAction(long dstPort) {
 		this.dstPort = dstPort;
 	}
 	
 	public String toString() {
-		return dstPort.toString();
+		return Long.toString(dstPort);
 	}
 
 	@Override
 	public FlowEntryAction getFlowEntryAction() {
 	    FlowEntryAction action = new FlowEntryAction();
-	    action.setActionOutput(new net.onrc.onos.ofcontroller.util.Port(dstPort.getNumber().shortValue()));
+	    action.setActionOutput(new net.onrc.onos.ofcontroller.util.Port((short) dstPort));
 	    return action;
 	}
 	
diff --git a/src/main/java/net/onrc/onos/intent/Match.java b/src/main/java/net/onrc/onos/intent/Match.java
index 308cfcf..5adb598 100644
--- a/src/main/java/net/onrc/onos/intent/Match.java
+++ b/src/main/java/net/onrc/onos/intent/Match.java
@@ -1,8 +1,8 @@
 package net.onrc.onos.intent;
 
 import net.floodlightcontroller.util.MACAddress;
-import net.onrc.onos.ofcontroller.networkgraph.Port;
-import net.onrc.onos.ofcontroller.networkgraph.Switch;
+//import net.onrc.onos.ofcontroller.networkgraph.Port;
+//import net.onrc.onos.ofcontroller.networkgraph.Switch;
 import net.onrc.onos.ofcontroller.util.FlowEntryMatch;
 
 /**
@@ -12,13 +12,13 @@
  */
 
 public class Match {
-	protected Switch sw;
+	protected long sw;
 	protected MACAddress srcMac;
 	protected MACAddress dstMac;
-	protected Port srcPort;
-
-	public Match(Switch sw, Port srcPort,
-				 MACAddress srcMac, MACAddress dstMac) {
+	protected long srcPort;
+	
+	public Match(long sw, long srcPort, 
+		     MACAddress srcMac, MACAddress dstMac) {
 		this.sw = sw;
 		this.srcPort = srcPort;
 		this.srcMac = srcMac;
@@ -43,12 +43,12 @@
 	    FlowEntryMatch match = new FlowEntryMatch();
 	    match.enableSrcMac(srcMac);
 	    match.enableDstMac(dstMac);
-	    match.enableInPort(new net.onrc.onos.ofcontroller.util.Port(srcPort.getNumber().shortValue()));
+	    match.enableInPort(new net.onrc.onos.ofcontroller.util.Port((short) srcPort));
 	    return match;
 	}
 
 	@Override
 	public String toString() {
-		return "(" + srcPort + "," + srcMac + "," + dstMac + ")";
+		return "Sw:" + sw + " (" + srcPort + "," + srcMac + "," + dstMac + ")";
 	}
 }
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PlanCalcRuntime.java b/src/main/java/net/onrc/onos/intent/runtime/PlanCalcRuntime.java
index 63892cb..2e0c563 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PlanCalcRuntime.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PlanCalcRuntime.java
@@ -17,11 +17,8 @@
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.intent.PathIntent;
 import net.onrc.onos.intent.ShortestPathIntent;
-import net.onrc.onos.ofcontroller.networkgraph.Link;
 import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
-import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
-import net.onrc.onos.ofcontroller.networkgraph.Port;
-import net.onrc.onos.ofcontroller.networkgraph.Switch;
+//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
 
 /**
  *
@@ -31,10 +28,10 @@
 
 public class PlanCalcRuntime {
 
-    NetworkGraph graph;
+//    NetworkGraph graph;
 
-    public PlanCalcRuntime(NetworkGraph graph) {
-	this.graph = graph;
+    public PlanCalcRuntime(/*NetworkGraph graph*/) {
+//	this.graph = graph;
     }
 
     public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
@@ -47,16 +44,20 @@
 	for(IntentOperation i : intentOps) {
 	    PathIntent intent = (PathIntent) i.intent;
 	    Intent parent = intent.getParentIntent();
-	    Port srcPort, dstPort, lastDstPort = null;
+	    long srcPort, dstPort;
+	    long lastDstSw = -1, lastDstPort = -1;
 	    MACAddress srcMac, dstMac;
 	    if(parent instanceof ShortestPathIntent) {
 		ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
-		Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
-		srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
+//		Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
+//		srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
+		srcPort = pathIntent.getSrcPortNumber();
 		srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
 		dstMac = MACAddress.valueOf(pathIntent.getDstMac());
-		Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
-		lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
+//		Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
+		lastDstSw = pathIntent.getDstSwitchDpid();
+//		lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
+		lastDstPort = pathIntent.getDstPortNumber();
 	    }
 	    else {
 		// TODO: log this error
@@ -64,18 +65,22 @@
 	    }
 	    List<FlowEntry> entries = new ArrayList<>();
 	    for(LinkEvent linkEvent : intent.getPath()) {
-		Link link = graph.getLink(linkEvent.getSrc().getDpid(),
-			  linkEvent.getSrc().getNumber(),
-			  linkEvent.getDst().getDpid(),
-			  linkEvent.getDst().getNumber());
-		Switch sw = link.getSrcSwitch();
-		dstPort = link.getSrcPort();
+//		Link link = graph.getLink(linkEvent.getSrc().getDpid(),
+//			  linkEvent.getSrc().getNumber(),
+//			  linkEvent.getDst().getDpid(),
+//			  linkEvent.getDst().getNumber());
+//		Switch sw = link.getSrcSwitch();
+		long sw = linkEvent.getSrc().getDpid();
+//		dstPort = link.getSrcPort();
+		dstPort = linkEvent.getSrc().getNumber();
 		FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
 		entries.add(fe);
-		srcPort = link.getDstPort();
+//		srcPort = link.getDstPort();
+		srcPort = linkEvent.getDst().getNumber();
 	    }
-	    if(lastDstPort != null) {
-		Switch sw = lastDstPort.getSwitch();
+	    if(lastDstSw >= 0 && lastDstPort >= 0) {
+		//Switch sw = lastDstPort.getSwitch();
+		long sw = lastDstSw;
 		dstPort = lastDstPort;
 		FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac, i.operator);
 		entries.add(fe);
@@ -103,6 +108,8 @@
 		case REMOVE:
 		    i -= 1;
 		    break;
+		default:
+		    break;
 		}
 		map.put(e, i);
 		System.out.println(e + " " + e.getOperator());
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PlanInstallModule.java b/src/main/java/net/onrc/onos/intent/runtime/PlanInstallModule.java
index cc780fb..adef594 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PlanInstallModule.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PlanInstallModule.java
@@ -17,10 +17,12 @@
 import net.onrc.onos.datagrid.IEventChannel;
 import net.onrc.onos.datagrid.IEventChannelListener;
 import net.onrc.onos.intent.FlowEntry;
+import net.onrc.onos.intent.Intent.IntentState;
+import net.onrc.onos.intent.IntentOperation;
 import net.onrc.onos.intent.IntentOperationList;
 import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
 import net.onrc.onos.ofcontroller.networkgraph.INetworkGraphService;
-import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -33,11 +35,13 @@
     private PlanCalcRuntime planCalc;
     private PlanInstallRuntime planInstall;
     private EventListener eventListener;
-    private IEventChannel<Long, IntentOperationList> channel;
+    private IEventChannel<Long, IntentStateList> intentStateChannel;
     private final static Logger log = LoggerFactory.getLogger(PlanInstallModule.class);
 
 
     private static final String PATH_INTENT_CHANNEL_NAME = "onos.pathintent";
+    private static final String INTENT_STATE_EVENT_CHANNEL_NAME = "onos.pathintent_state";
+
     
     @Override
     public void init(FloodlightModuleContext context)
@@ -46,9 +50,9 @@
 	networkGraph = context.getServiceImpl(INetworkGraphService.class);
 	datagridService = context.getServiceImpl(IDatagridService.class);
 	flowPusher = context.getServiceImpl(IFlowPusherService.class);
-	NetworkGraph graph = networkGraph.getNetworkGraph();
-	planCalc = new PlanCalcRuntime(graph);
-	planInstall = new PlanInstallRuntime(graph, floodlightProvider, flowPusher);
+//	NetworkGraph graph = networkGraph.getNetworkGraph();
+	planCalc = new PlanCalcRuntime();
+	planInstall = new PlanInstallRuntime(floodlightProvider, flowPusher);
 	eventListener = new EventListener();
     }
 
@@ -56,6 +60,7 @@
     	implements IEventChannelListener<Long, IntentOperationList> {
 	
 	private BlockingQueue<IntentOperationList> intentQueue = new LinkedBlockingQueue<>();
+	private Long key = Long.valueOf(0);
 	
 	@Override
 	public void run() {
@@ -74,11 +79,44 @@
 	    log.debug("Processing OperationList {}", intents);
 	    List<Set<FlowEntry>> plan = planCalc.computePlan(intents);
 	    log.debug("Plan: {}", plan);
-	    planInstall.installPlan(plan);
+	    boolean success = planInstall.installPlan(plan);
+	    
+	    sendNotifications(intents, true, success);
+	}
+	
+	private void sendNotifications(IntentOperationList intents, boolean installed, boolean success) {
+	    IntentStateList states = new IntentStateList();
+	    for(IntentOperation i : intents) {
+		IntentState newState;
+		switch(i.operator) {
+		case REMOVE:
+		    if(installed) {
+			newState = success ? IntentState.DEL_ACK : IntentState.DEL_PENDING;
+		    }
+		    else {
+			newState = IntentState.DEL_REQ;
+		    }
+		    break;
+		case ADD:
+		default:
+		    if(installed) {
+			newState = success ? IntentState.INST_ACK : IntentState.INST_NACK;
+		    }
+		    else {
+			newState = IntentState.INST_REQ;
+		    }
+		    break;
+		}
+		states.put(i.intent.getId(), newState);
+	    }
+	    intentStateChannel.addEntry(key, states);
+	    key += 1;
 	}
 	
 	@Override
 	public void entryAdded(IntentOperationList value) {
+	    sendNotifications(value, false, false);
+	    
 	    log.debug("Added OperationList {}", value);
 	    try {
 		intentQueue.put(value);
@@ -99,11 +137,16 @@
     }
     @Override
     public void startUp(FloodlightModuleContext context) {
-	channel = datagridService.addListener(PATH_INTENT_CHANNEL_NAME, 
+	// start subscriber
+	datagridService.addListener(PATH_INTENT_CHANNEL_NAME, 
 				    	      eventListener, 
 				              Long.class, 
 				              IntentOperationList.class);
 	eventListener.start();
+	// start publisher
+	intentStateChannel = datagridService.createChannel(INTENT_STATE_EVENT_CHANNEL_NAME, 
+						Long.class, 
+						IntentStateList.class);
     }
     
     @Override
diff --git a/src/main/java/net/onrc/onos/intent/runtime/PlanInstallRuntime.java b/src/main/java/net/onrc/onos/intent/runtime/PlanInstallRuntime.java
index 82e0d23..4325c4e 100644
--- a/src/main/java/net/onrc/onos/intent/runtime/PlanInstallRuntime.java
+++ b/src/main/java/net/onrc/onos/intent/runtime/PlanInstallRuntime.java
@@ -9,7 +9,7 @@
 import net.floodlightcontroller.core.IOFSwitch;
 import net.onrc.onos.intent.FlowEntry;
 import net.onrc.onos.ofcontroller.flowprogrammer.IFlowPusherService;
-import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
 import net.onrc.onos.ofcontroller.util.Pair;
 
 import org.slf4j.Logger;
@@ -22,34 +22,36 @@
  */
 
 public class PlanInstallRuntime {
-    NetworkGraph graph;
+//    NetworkGraph graph;
     IFlowPusherService pusher;
     IFloodlightProviderService provider;
     private final static Logger log = LoggerFactory.getLogger(PlanInstallRuntime.class);
 
-    public PlanInstallRuntime(NetworkGraph graph, 
+    public PlanInstallRuntime(//NetworkGraph graph, 
 	    		      IFloodlightProviderService provider,
 	                      IFlowPusherService pusher) {
-	this.graph = graph;
+//	this.graph = graph;
 	this.provider = provider;
 	this.pusher = pusher;
     }
 
-    public void installPlan(List<Set<FlowEntry>> plan) {
+    public boolean installPlan(List<Set<FlowEntry>> plan) {
 	Map<Long,IOFSwitch> switches = provider.getSwitches();
 	log.debug("IOFSwitches: {}", switches);
 	for(Set<FlowEntry> phase : plan) {
 	    Set<Pair<IOFSwitch, net.onrc.onos.ofcontroller.util.FlowEntry>> entries = new HashSet<>();
 	    // convert flow entries and create pairs
 	    for(FlowEntry entry : phase) {
-		entries.add(new Pair<>(switches.get(entry.getSwitch().getDpid()), 
-			entry.getFlowEntry()));
+		IOFSwitch sw = switches.get(entry.getSwitch());
+		entries.add(new Pair<>(sw, entry.getFlowEntry()));
 	    }
 	    log.debug("Pushing flow entries: {}", entries);
 	    // push flow entries to switches
 	    pusher.pushFlowEntries(entries);
 	    // TODO: wait for confirmation messages before proceeding
 	}
+	// TODO: we assume that the plan installation succeeds for now
+	return true;
     }
 
 }
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 cb4ab9e..24f61f3 100755
--- a/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
+++ b/src/test/java/net/onrc/onos/intent/runtime/UseCaseTest.java
@@ -138,7 +138,7 @@
 		IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
 
 		// compile low-level intents into flow entry installation plan
-		PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
+		PlanCalcRuntime runtime2 = new PlanCalcRuntime();
 		List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
 
 		// show results
@@ -163,7 +163,7 @@
 		IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
 
 		// compile low-level intents into flow entry installation plan
-		PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
+		PlanCalcRuntime runtime2 = new PlanCalcRuntime();
 		List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
 
 		// show results
@@ -188,7 +188,7 @@
 		IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
 
 		// compile low-level intents into flow entry installation plan
-		PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
+		PlanCalcRuntime runtime2 = new PlanCalcRuntime();
 		List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
 
 		// show results
@@ -220,7 +220,7 @@
 		IntentOperationList pathIntentOpList = runtime1.executeIntentOperations(opList);
 
 		// compile low-level intents into flow entry installation plan
-		PlanCalcRuntime runtime2 = new PlanCalcRuntime(g);
+		PlanCalcRuntime runtime2 = new PlanCalcRuntime();
 		List<Set<FlowEntry>> plan = runtime2.computePlan(pathIntentOpList);
 
 		// show results step1