Connecting packet paths to optical tunnels visually.

Change-Id: Ib6a8cefd9e6eb466e38e305b2fcda4b40a8854fd
diff --git a/tools/test/cells/tom b/tools/test/cells/tom
index e445e5e..9db8758 100644
--- a/tools/test/cells/tom
+++ b/tools/test/cells/tom
@@ -5,4 +5,4 @@
 export OCN="192.168.56.103"
 export OCI="${OC1}"
 
-export ONOS_FEATURES=webconsole,onos-api,onos-core-trivial,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-fwd,onos-app-proxyarp,onos-app-tvue
+export ONOS_FEATURES=webconsole,onos-api,onos-core-trivial,onos-cli,onos-rest,onos-gui,onos-openflow,onos-app-fwd,onos-app-proxyarp,onos-app-optical
diff --git a/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java b/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java
index aef9e95..cad7228 100644
--- a/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java
+++ b/web/gui/src/main/java/org/onlab/onos/gui/TopologyMessages.java
@@ -40,11 +40,11 @@
 import org.onlab.onos.net.device.DeviceService;
 import org.onlab.onos.net.host.HostEvent;
 import org.onlab.onos.net.host.HostService;
-import org.onlab.onos.net.intent.ConnectivityIntent;
 import org.onlab.onos.net.intent.Intent;
 import org.onlab.onos.net.intent.IntentService;
 import org.onlab.onos.net.intent.LinkCollectionIntent;
 import org.onlab.onos.net.intent.OpticalConnectivityIntent;
+import org.onlab.onos.net.intent.OpticalPathIntent;
 import org.onlab.onos.net.intent.PathIntent;
 import org.onlab.onos.net.link.LinkEvent;
 import org.onlab.onos.net.link.LinkService;
@@ -384,9 +384,14 @@
                 if (installables != null) {
                     for (Intent installable : installables) {
                         String cls = isOptical ? trafficClass.type + " optical" : trafficClass.type;
-                        if (installable instanceof ConnectivityIntent) {
-                            addPathTraffic(paths, cls, (ConnectivityIntent) installable);
+                        if (installable instanceof PathIntent) {
+                            addPathTraffic(paths, cls, ((PathIntent) installable).path().links());
+                        } else if (installable instanceof LinkCollectionIntent) {
+                            addPathTraffic(paths, cls, ((LinkCollectionIntent) installable).links());
+                        } else if (installable instanceof OpticalPathIntent) {
+                            addPathTraffic(paths, cls, ((OpticalPathIntent) installable).path().links());
                         }
+
                     }
                 }
             }
@@ -397,12 +402,10 @@
 
     // Adds the link segments (path or tree) associated with the specified
     // connectivity intent
-    protected void addPathTraffic(ArrayNode paths, String type,
-                                  ConnectivityIntent installable) {
+    protected void addPathTraffic(ArrayNode paths, String type, Iterable<Link> links) {
         ObjectNode pathNode = mapper.createObjectNode();
         ArrayNode linksNode = mapper.createArrayNode();
 
-        Iterable<Link> links = pathLinks(installable);
         if (links != null) {
             ArrayNode labels = mapper.createArrayNode();
             boolean hasTraffic = true; // FIXME
@@ -423,15 +426,6 @@
         }
     }
 
-    private Iterable<Link> pathLinks(ConnectivityIntent intent) {
-        if (intent instanceof PathIntent) {
-            return ((PathIntent) intent).path().links();
-        } else if (intent instanceof LinkCollectionIntent) {
-            return ((LinkCollectionIntent) intent).links();
-        }
-        return null;
-    }
-
     // Produces compact string representation of a link.
     private static String compactLinkString(Link link) {
         return String.format(COMPACT, link.src().elementId(), link.src().port(),
diff --git a/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java b/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
index 10b5785..eee03ed 100644
--- a/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
+++ b/web/gui/src/main/java/org/onlab/onos/gui/TopologyWebSocket.java
@@ -29,7 +29,6 @@
 import org.onlab.onos.net.Host;
 import org.onlab.onos.net.HostId;
 import org.onlab.onos.net.Link;
-import org.onlab.onos.net.Path;
 import org.onlab.onos.net.device.DeviceEvent;
 import org.onlab.onos.net.device.DeviceListener;
 import org.onlab.onos.net.flow.DefaultTrafficSelector;
@@ -378,14 +377,20 @@
     // Indicates whether the specified intent involves all of the given edge points.
     private boolean isIntentRelevant(OpticalConnectivityIntent opticalIntent,
                                      Set<Intent> intents) {
+        Link ccSrc = getFirstLink(opticalIntent.getSrcConnectPoint(), false);
+        Link ccDst = getFirstLink(opticalIntent.getDst(), true);
+
         for (Intent intent : intents) {
             List<Intent> installables = intentService.getInstallableIntents(intent.id());
             for (Intent installable : installables) {
                 if (installable instanceof PathIntent) {
-                    Path path = ((PathIntent) installable).path();
-                    if (opticalIntent.getSrcConnectPoint().equals(path.src()) &&
-                            opticalIntent.getDst().equals(path.dst())) {
-                        return true;
+                    List<Link> links = ((PathIntent) installable).path().links();
+                    if (links.size() == 3) {
+                        Link tunnel = links.get(1);
+                        if (tunnel.src().equals(ccSrc.src()) &&
+                                tunnel.dst().equals(ccDst.dst())) {
+                            return true;
+                        }
                     }
                 }
             }
@@ -393,6 +398,15 @@
         return false;
     }
 
+    private Link getFirstLink(ConnectPoint point, boolean ingress) {
+        for (Link link : linkService.getLinks(point)) {
+            if (point.equals(ingress ? link.src() : link.dst())) {
+                return link;
+            }
+        }
+        return null;
+    }
+
     // Produces a set of all host ids listed in the specified JSON array.
     private Set<Host> getHosts(ArrayNode array) {
         Set<Host> hosts = new HashSet<>();