blob: 18e962fbd71d4e3f4d88458ba8748845902670fc [file] [log] [blame]
package net.onrc.onos.intent.runtime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.intent.FlowEntry;
import net.onrc.onos.intent.Intent;
import net.onrc.onos.intent.IntentOperationList;
import net.onrc.onos.intent.PathIntent;
import net.onrc.onos.intent.PathIntentMap;
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;
/**
*
* @author Brian O'Connor <bocon@onlab.us>
*
*/
public class PlanCalcRuntime {
NetworkGraph graph;
protected PathIntentMap intents;
protected Set<Collection<FlowEntry>> flowEntries;
protected List<Set<FlowEntry>> plan;
public PlanCalcRuntime(NetworkGraph graph) {
this.graph = graph;
this.flowEntries = new HashSet<>();
this.plan = new ArrayList<>();
this.intents = new PathIntentMap();
}
public void addIntents(IntentOperationList intentOpList) {
intents.executeOperations(intentOpList);
computeFlowEntries();
constructPlan();
}
public List<Set<FlowEntry>> getPlan() {
return plan;
}
public void computeFlowEntries() {
for(Intent i : intents.getAllIntents()) {
PathIntent intent = (PathIntent)i;
Intent parent = intent.getParentIntent();
Port srcPort, dstPort, lastDstPort = null;
MACAddress srcMac, dstMac;
if(parent instanceof ShortestPathIntent) {
ShortestPathIntent pathIntent = (ShortestPathIntent) parent;
Switch srcSwitch = graph.getSwitch(pathIntent.getSrcSwitchDpid());
srcPort = srcSwitch.getPort(pathIntent.getSrcPortNumber());
srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
dstMac = MACAddress.valueOf(pathIntent.getDstMac());
Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
}
else {
// TODO: log this error
continue;
}
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();
FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac);
entries.add(fe);
srcPort = link.getDstPort();
}
if(lastDstPort != null) {
Switch sw = lastDstPort.getSwitch();
dstPort = lastDstPort;
FlowEntry fe = new FlowEntry(sw, srcPort, dstPort, srcMac, dstMac);
entries.add(fe);
}
// install flow entries in reverse order
Collections.reverse(entries);
flowEntries.add(entries);
}
}
public void constructPlan() {
Map<FlowEntry, Integer> map = new HashMap<>();
for(Collection<FlowEntry> c : flowEntries) {
for(FlowEntry e: c) {
Integer i = map.get(e);
if(i == null) {
map.put(e, 1);
}
else {
i += 1;
}
}
}
// really simple first iteration of plan
//TODO: optimize the map in phases
plan.add(map.keySet());
}
}