Renamed the intent package
net.onrc.onos.intent.* => net.onrc.onos.core.intent.*
Change-Id: Id61f79ed52acf3b91af4ebad2515ac5b7d6dc5e1
diff --git a/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
new file mode 100644
index 0000000..7c92115
--- /dev/null
+++ b/src/main/java/net/onrc/onos/core/intent/runtime/PlanCalcRuntime.java
@@ -0,0 +1,155 @@
+package net.onrc.onos.core.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.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import net.floodlightcontroller.util.MACAddress;
+import net.onrc.onos.core.intent.FlowEntry;
+import net.onrc.onos.core.intent.Intent;
+import net.onrc.onos.core.intent.IntentOperation;
+import net.onrc.onos.core.intent.IntentOperationList;
+import net.onrc.onos.core.intent.PathIntent;
+import net.onrc.onos.core.intent.ShortestPathIntent;
+import net.onrc.onos.core.intent.IntentOperation.Operator;
+import net.onrc.onos.ofcontroller.networkgraph.LinkEvent;
+//import net.onrc.onos.ofcontroller.networkgraph.NetworkGraph;
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ *
+ * @author Brian O'Connor <bocon@onlab.us>
+ *
+ */
+
+public class PlanCalcRuntime {
+
+// NetworkGraph graph;
+ private final static Logger log = LoggerFactory.getLogger(PlanCalcRuntime.class);
+
+ public PlanCalcRuntime(/*NetworkGraph graph*/) {
+// this.graph = graph;
+ }
+
+ public List<Set<FlowEntry>> computePlan(IntentOperationList intentOps) {
+ long start = System.nanoTime();
+ List<Collection<FlowEntry>> flowEntries = computeFlowEntries(intentOps);
+ long step1 = System.nanoTime();
+ List<Set<FlowEntry>> plan = buildPhases(flowEntries);
+ long step2 = System.nanoTime();
+ log.error("MEASUREMENT: Compute flow entries: {} ns, Build phases: {} ns",
+ (step1 - start), (step2 - step1));
+ return plan;
+ }
+
+ private List<Collection<FlowEntry>> computeFlowEntries(IntentOperationList intentOps) {
+ List<Collection<FlowEntry>> flowEntries = new LinkedList<>();
+ for(IntentOperation i : intentOps) {
+ if(!(i.intent instanceof PathIntent)) {
+ log.warn("Not a path intent: {}", i);
+ continue;
+ }
+ PathIntent intent = (PathIntent) i.intent;
+ Intent parent = intent.getParentIntent();
+ 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());
+ srcPort = pathIntent.getSrcPortNumber();
+ srcMac = MACAddress.valueOf(pathIntent.getSrcMac());
+ dstMac = MACAddress.valueOf(pathIntent.getDstMac());
+// Switch dstSwitch = graph.getSwitch(pathIntent.getDstSwitchDpid());
+ lastDstSw = pathIntent.getDstSwitchDpid();
+// lastDstPort = dstSwitch.getPort(pathIntent.getDstPortNumber());
+ lastDstPort = pathIntent.getDstPortNumber();
+ }
+ else {
+ log.warn("Unsupported Intent: {}", parent);
+ 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();
+ 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 = linkEvent.getDst().getNumber();
+ }
+ 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);
+ }
+ // install flow entries in reverse order
+ Collections.reverse(entries);
+ flowEntries.add(entries);
+ }
+ return flowEntries;
+ }
+
+ private List<Set<FlowEntry>> buildPhases(List<Collection<FlowEntry>> flowEntries) {
+ Map<FlowEntry, Integer> map = new HashMap<>();
+ List<Set<FlowEntry>> plan = new ArrayList<>();
+ for(Collection<FlowEntry> c : flowEntries) {
+ for(FlowEntry e : c) {
+ Integer i = map.get(e);
+ if(i == null) {
+ i = Integer.valueOf(0);
+ }
+ switch(e.getOperator()) {
+ case ADD:
+ i += 1;
+ break;
+ case REMOVE:
+ i -= 1;
+ break;
+ default:
+ break;
+ }
+ map.put(e, i);
+ // System.out.println(e + " " + e.getOperator());
+ }
+ }
+
+ // really simple first iteration of plan
+ //TODO: optimize the map in phases
+ Set<FlowEntry> phase = new HashSet<>();
+ for(FlowEntry e : map.keySet()) {
+ Integer i = map.get(e);
+ if(i == 0) {
+ continue;
+ }
+ else if(i > 0) {
+ e.setOperator(Operator.ADD);
+ }
+ else if(i < 0) {
+ e.setOperator(Operator.REMOVE);
+ }
+ phase.add(e);
+ }
+ plan.add(phase);
+
+ return plan;
+ }
+}