ONOS-3460 - Link provider that enforces strict configuration

This provider uses the "links" configuration of the network
config and only allows discovery of links that are in
the config.

Refactoring will be done in a subsequent patch set - the DiscoveryContext and
LinkDiscovery classes are duplicates, they need to be refactored so the
LLDP provider and the Network Config provider can share them.

Change-Id: I4de12fc1c4ffa05e3cac7767b8a31f48ba379f6c
diff --git a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
index e2d9214..49d5155 100644
--- a/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
+++ b/web/gui/src/main/java/org/onosproject/ui/impl/TopologyViewMessageHandlerBase.java
@@ -278,6 +278,7 @@
         ObjectNode payload = objectNode()
                 .put("id", compactLinkString(link))
                 .put("type", link.type().toString().toLowerCase())
+                .put("expected", link.isExpected())
                 .put("online", link.state() == Link.State.ACTIVE)
                 .put("linkWidth", 1.2)
                 .put("src", link.src().deviceId().toString())
diff --git a/web/gui/src/main/webapp/app/view/topo/topo.css b/web/gui/src/main/webapp/app/view/topo/topo.css
index 69f500f..1270979 100644
--- a/web/gui/src/main/webapp/app/view/topo/topo.css
+++ b/web/gui/src/main/webapp/app/view/topo/topo.css
@@ -526,6 +526,12 @@
     opacity: .5;
     stroke-dasharray: 8 4;
 }
+/* FIXME: Review for not-permitted links */
+#ov-topo svg .link.not-permitted {
+    stroke: rgb(255,0,0);
+    stroke-width: 5.0;
+    stroke-dasharray: 8 4;
+}
 
 #ov-topo svg .link.secondary {
     stroke-width: 3px;
diff --git a/web/gui/src/main/webapp/app/view/topo/topoForce.js b/web/gui/src/main/webapp/app/view/topo/topoForce.js
index 3c68f3e..21137af 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoForce.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoForce.js
@@ -323,7 +323,8 @@
             .domain([1, 12])
             .range([widthRatio, 12 * widthRatio])
             .clamp(true),
-        allLinkTypes = 'direct indirect optical tunnel';
+        allLinkTypes = 'direct indirect optical tunnel',
+        allLinkSubTypes = 'inactive not-permitted';
 
     function restyleLinkElement(ldata, immediate) {
         // this fn's job is to look at raw links and decide what svg classes
@@ -333,6 +334,7 @@
             type = ldata.type(),
             lw = ldata.linkWidth(),
             online = ldata.online(),
+            modeCls = ldata.expected() ? 'inactive' : 'not-permitted',
             delay = immediate ? 0 : 1000;
 
         // FIXME: understand why el is sometimes undefined on addLink events...
@@ -343,7 +345,8 @@
         // a more efficient way to fix it.
         if (el && !el.empty()) {
             el.classed('link', true);
-            el.classed('inactive', !online);
+            el.classed(allLinkSubTypes, false);
+            el.classed(modeCls, !online);
             el.classed(allLinkTypes, false);
             if (type) {
                 el.classed(type, true);
diff --git a/web/gui/src/main/webapp/app/view/topo/topoModel.js b/web/gui/src/main/webapp/app/view/topo/topoModel.js
index 282a066..ed9eeb1 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoModel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoModel.js
@@ -198,6 +198,11 @@
                     t = lnk.fromTarget;
                 return (s && s.type) || (t && t.type) || defaultLinkType;
             },
+            expected: function () {
+                var s = lnk.fromSource,
+                    t = lnk.fromTarget;
+                return (s && s.expected) && (t && t.expected);
+            },
             online: function () {
                 var s = lnk.fromSource,
                     t = lnk.fromTarget,
diff --git a/web/gui/src/main/webapp/app/view/topo/topoPanel.js b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
index af2c4bc..37faf29 100644
--- a/web/gui/src/main/webapp/app/view/topo/topoPanel.js
+++ b/web/gui/src/main/webapp/app/view/topo/topoPanel.js
@@ -301,8 +301,12 @@
         return linkTypePres[d.type()] || d.type();
     }
 
+    function linkExpected(d) {
+        return d.expected();
+    }
+
     var coreOrder = [
-            'Type', '-',
+            'Type', 'Expected', '-',
             'A_type', 'A_id', 'A_label', 'A_port', '-',
             'B_type', 'B_id', 'B_label', 'B_port', '-'
         ],
@@ -332,6 +336,7 @@
             propOrder: order,
             props: {
                 Type: linkType(data),
+                Expected: linkExpected(data),
 
                 A_type: data.source.class,
                 A_id: data.source.id,