optical intent

Change-Id: I23714985a2fe1e3bbc59deff2d267007750d0420
diff --git a/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
index e91235c..9f77cfd 100644
--- a/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
+++ b/apps/optical/src/main/java/org/onlab/onos/optical/provisioner/OpticalPathProvisioner.java
@@ -30,7 +30,7 @@
 import org.onlab.onos.net.topology.LinkWeight;
 import org.onlab.onos.net.topology.Topology;
 import org.onlab.onos.net.topology.TopologyEdge;
-import org.onlab.onos.net.topology.TopologyGraph;
+
 import org.onlab.onos.net.topology.TopologyService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -120,7 +120,6 @@
            }
 
            Topology topology = topologyService.currentTopology();
-           TopologyGraph graph = topologyService.getGraph(topology);
 
            LinkWeight weight = new LinkWeight() {
                @Override
diff --git a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
index 1ad828d..afa0004 100644
--- a/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
+++ b/core/api/src/main/java/org/onlab/onos/net/intent/OpticalPathIntent.java
@@ -13,8 +13,8 @@
 
 public class OpticalPathIntent extends OpticalConnectivityIntent {
     private final Path path;
-    private final TrafficSelector opticalMatch;
-    private final TrafficTreatment opticalAction;
+    // private final TrafficSelector opticalMatch;
+    // private final TrafficTreatment opticalAction;
 
     public OpticalPathIntent(ApplicationId appId,
             ConnectPoint src,
@@ -23,29 +23,29 @@
             TrafficTreatment action,
             Path path) {
         super(appId, src, dst);
-        this.opticalMatch = match;
-        this.opticalAction = action;
+        // this.opticalMatch = match;
+        // this.opticalAction = action;
         this.path = path;
     }
 
-    public OpticalPathIntent() {
-        this.opticalMatch = null;
-        this.opticalAction = null;
+    protected OpticalPathIntent() {
+        // this.opticalMatch = null;
+        // this.opticalAction = null;
         this.path = null;
     }
 
     public Path path() {
         return path;
     }
-
+/*
     public TrafficSelector selector() {
-        return opticalMatch;
+        // return opticalMatch;
     }
 
     public TrafficTreatment treatment() {
-        return opticalAction;
+        // return opticalAction;
     }
-
+*/
     @Override
     public boolean isInstallable() {
         return true;
@@ -55,8 +55,8 @@
     public String toString() {
         return MoreObjects.toStringHelper(getClass())
                 .add("id", id())
-                .add("match", opticalMatch)
-                .add("action", opticalAction)
+                //.add("match", opticalMatch)
+                //.add("action", opticalAction)
                 .add("ingressPort", this.getSrcConnectPoint())
                 .add("egressPort", this.getDst())
                 .add("path", path)
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
index e44a01b..9b98cec 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalConnectivityIntentCompiler.java
@@ -14,7 +14,7 @@
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.onlab.onos.CoreService;
 import org.onlab.onos.net.ConnectPoint;
-import org.onlab.onos.net.DefaultEdgeLink;
+
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.Path;
 import org.onlab.onos.net.flow.TrafficSelector;
@@ -84,9 +84,9 @@
         }
 
         List<Link> links = new ArrayList<>();
-        links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
+        // links.add(DefaultEdgeLink.createEdgeLink(intent.getSrcConnectPoint(), true));
         links.addAll(path.links());
-        links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
+        //links.add(DefaultEdgeLink.createEdgeLink(intent.getDst(), false));
 
         TrafficSelector opticalSelector = null;
         TrafficTreatment opticalTreatment = null;
diff --git a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
index 1f7ef68..f24916f 100644
--- a/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
+++ b/core/net/src/main/java/org/onlab/onos/net/intent/impl/OpticalPathIntentInstaller.java
@@ -3,9 +3,8 @@
 import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
 import static org.slf4j.LoggerFactory.getLogger;
 
-import java.util.Iterator;
+
 import java.util.List;
-import java.util.concurrent.Future;
 
 import org.apache.felix.scr.annotations.Activate;
 import org.apache.felix.scr.annotations.Component;
@@ -16,7 +15,6 @@
 import org.onlab.onos.CoreService;
 import org.onlab.onos.net.ConnectPoint;
 import org.onlab.onos.net.Link;
-import org.onlab.onos.net.flow.CompletedBatchOperation;
 import org.onlab.onos.net.flow.DefaultFlowRule;
 import org.onlab.onos.net.flow.DefaultTrafficSelector;
 import org.onlab.onos.net.flow.DefaultTrafficTreatment;
@@ -30,11 +28,14 @@
 import org.onlab.onos.net.intent.IntentExtensionService;
 import org.onlab.onos.net.intent.IntentInstaller;
 import org.onlab.onos.net.intent.OpticalPathIntent;
+import org.onlab.onos.net.resource.DefaultLinkResourceRequest;
 import org.onlab.onos.net.resource.Lambda;
+import org.onlab.onos.net.resource.LambdaResourceAllocation;
 import org.onlab.onos.net.resource.LinkResourceAllocations;
 import org.onlab.onos.net.resource.LinkResourceRequest;
 import org.onlab.onos.net.resource.LinkResourceService;
-import org.onlab.onos.net.resource.ResourceRequest;
+import org.onlab.onos.net.resource.ResourceAllocation;
+import org.onlab.onos.net.resource.ResourceType;
 import org.onlab.onos.net.topology.TopologyService;
 import org.slf4j.Logger;
 
@@ -67,7 +68,7 @@
 
     private ApplicationId appId;
 
-    final static short WAVELENGTH = 80;
+    //final short WAVELENGTH = 80;
 
     @Activate
     public void activate() {
@@ -82,44 +83,72 @@
 
     @Override
     public List<FlowRuleBatchOperation> install(OpticalPathIntent intent) {
-        Lambda la = assignWavelength(intent.path().links());
-        if (la == null) {
-            return null;
-        }
-        // resourceService.requestResources(la);
-        // la.toInt();
-        //intent.selector().criteria();
+        LinkResourceAllocations allocations = assignWavelength(intent);
 
-        //TrafficSelector.Builder builder = DefaultTrafficSelector.builder();
-        //builder.matchLambdaType(la.toInt())
-        //        .matchInport(intent.getSrcConnectPoint().port());
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        selectorBuilder.matchInport(intent.getSrcConnectPoint().port());
 
-        TrafficSelector.Builder builder =
-                DefaultTrafficSelector.builder(intent.selector());
-        Iterator<Link> links = intent.path().links().iterator();
-        ConnectPoint prev = links.next().dst();
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
         List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
-        // TODO Generate multiple batches
-        while (links.hasNext()) {
-            builder.matchInport(prev.port());
-            Link link = links.next();
-            TrafficTreatment treatment = builder()
-                    .setOutput(link.src().port()).build();
+        ConnectPoint prev = intent.getSrcConnectPoint();
 
-            FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
-                    builder.build(),
-                    treatment,
+        //TODO throw exception if the lambda was not assigned successfully
+        for (Link link : intent.path().links()) {
+            Lambda la = null;
+            for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
+                if (allocation.type() == ResourceType.LAMBDA) {
+                    la = ((LambdaResourceAllocation) allocation).lambda();
+                    break;
+                }
+            }
+
+            if (la == null) {
+                log.info("Lambda was not assigned successfully");
+                return null;
+            }
+
+            treatmentBuilder.setOutput(link.src().port());
+            //treatmentBuilder.setLambda(la.toInt());
+
+            FlowRule rule = new DefaultFlowRule(prev.deviceId(),
+                    selectorBuilder.build(),
+                    treatmentBuilder.build(),
                     100,
                     appId,
                     100,
                     true);
             rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+
             prev = link.dst();
+            selectorBuilder.matchInport(link.dst().port());
+            //selectorBuilder.setLambda(la.toInt());
         }
+
+        // build the last T port rule
+        TrafficTreatment treatmentLast = builder()
+                .setOutput(intent.getDst().port()).build();
+        FlowRule rule = new DefaultFlowRule(intent.getDst().deviceId(),
+                selectorBuilder.build(),
+                treatmentLast,
+                100,
+                appId,
+                100,
+                true);
+        rules.add(new FlowRuleBatchEntry(FlowRuleOperation.ADD, rule));
+
         return Lists.newArrayList(new FlowRuleBatchOperation(rules));
     }
 
-    private Lambda assignWavelength(List<Link> links) {
+    private LinkResourceAllocations assignWavelength(OpticalPathIntent intent) {
+        LinkResourceRequest.Builder request = DefaultLinkResourceRequest.builder(intent.id(),
+                intent.path().links())
+                .addLambdaRequest();
+        LinkResourceAllocations retLambda = resourceService.requestResources(request.build());
+        return retLambda;
+    }
+
+    /*private Lambda assignWavelength(List<Link> links) {
         // TODO More wavelength assignment algorithm
         int wavenum = 0;
         Iterator<Link> itrlink = links.iterator();
@@ -154,31 +183,64 @@
             //}
         }
         return false;
-    }
+    }*/
 
     @Override
     public List<FlowRuleBatchOperation> uninstall(OpticalPathIntent intent) {
-        TrafficSelector.Builder builder =
-                DefaultTrafficSelector.builder(intent.selector());
-        Iterator<Link> links = intent.path().links().iterator();
-        ConnectPoint prev = links.next().dst();
+        LinkResourceAllocations allocations = resourceService.getAllocation(intent.id());
+
+        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
+        selectorBuilder.matchInport(intent.getSrcConnectPoint().port());
+
+        TrafficTreatment.Builder treatmentBuilder = DefaultTrafficTreatment.builder();
+
         List<FlowRuleBatchEntry> rules = Lists.newLinkedList();
-        // TODO Generate multiple batches
-        while (links.hasNext()) {
-            builder.matchInport(prev.port());
-            Link link = links.next();
-            TrafficTreatment treatment = builder()
-                    .setOutput(link.src().port()).build();
-            FlowRule rule = new DefaultFlowRule(link.src().deviceId(),
-                    builder.build(),
-                    treatment,
+        ConnectPoint prev = intent.getSrcConnectPoint();
+
+        //TODO throw exception if the lambda was not retrieved successfully
+        for (Link link : intent.path().links()) {
+            Lambda la = null;
+            for (ResourceAllocation allocation : allocations.getResourceAllocation(link)) {
+                if (allocation.type() == ResourceType.LAMBDA) {
+                    la = ((LambdaResourceAllocation) allocation).lambda();
+                    break;
+                }
+            }
+
+            if (la == null) {
+                log.info("Lambda was not retrieved successfully");
+                return null;
+            }
+
+            treatmentBuilder.setOutput(link.src().port());
+            //treatmentBuilder.setLambda(la.toInt());
+
+            FlowRule rule = new DefaultFlowRule(prev.deviceId(),
+                    selectorBuilder.build(),
+                    treatmentBuilder.build(),
                     100,
                     appId,
                     100,
                     true);
             rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
+
             prev = link.dst();
+            selectorBuilder.matchInport(link.dst().port());
+            //selectorBuilder.setLambda(la.toInt());
         }
+
+        // build the last T port rule
+        TrafficTreatment treatmentLast = builder()
+                .setOutput(intent.getDst().port()).build();
+        FlowRule rule = new DefaultFlowRule(intent.getDst().deviceId(),
+                selectorBuilder.build(),
+                treatmentLast,
+                100,
+                appId,
+                100,
+                true);
+        rules.add(new FlowRuleBatchEntry(FlowRuleOperation.REMOVE, rule));
+
         return Lists.newArrayList(new FlowRuleBatchOperation(rules));
     }