ONOS-197: Ignore Link with missing Device

- Catch, log, and skip Link edge creation failure.
- log topology error details

Change-Id: I3cd44a86ed6641c49923f6ed4d2dbaf1f97511d0
diff --git a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
index ca64d1d..5e4d050 100644
--- a/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
+++ b/core/api/src/main/java/org/onlab/onos/net/topology/DefaultGraphDescription.java
@@ -15,14 +15,18 @@
  */
 package org.onlab.onos.net.topology;
 
+import static org.slf4j.LoggerFactory.getLogger;
+
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Maps;
+
 import org.onlab.onos.net.AbstractDescription;
 import org.onlab.onos.net.ConnectPoint;
 import org.onlab.onos.net.Device;
 import org.onlab.onos.net.DeviceId;
 import org.onlab.onos.net.Link;
 import org.onlab.onos.net.SparseAnnotations;
+import org.slf4j.Logger;
 
 import java.util.Map;
 
@@ -32,6 +36,8 @@
 public class DefaultGraphDescription extends AbstractDescription
         implements GraphDescription {
 
+    private static final Logger log = getLogger(DefaultGraphDescription.class);
+
     private final long nanos;
     private final ImmutableSet<TopologyVertex> vertexes;
     private final ImmutableSet<TopologyEdge> edges;
@@ -87,8 +93,12 @@
     private ImmutableSet<TopologyEdge> buildEdges(Iterable<Link> links) {
         ImmutableSet.Builder<TopologyEdge> edges = ImmutableSet.builder();
         for (Link link : links) {
-            edges.add(new DefaultTopologyEdge(vertexOf(link.src()),
-                                              vertexOf(link.dst()), link));
+            try {
+                edges.add(new DefaultTopologyEdge(vertexOf(link.src()),
+                                                  vertexOf(link.dst()), link));
+            } catch (IllegalArgumentException e) {
+                log.debug("Ignoring {}, missing vertex", link, e);
+            }
         }
         return edges.build();
     }
diff --git a/core/api/src/test/java/org/onlab/onos/net/topology/DefaultGraphDescriptionTest.java b/core/api/src/test/java/org/onlab/onos/net/topology/DefaultGraphDescriptionTest.java
index 4b229d8..5ff93671 100644
--- a/core/api/src/test/java/org/onlab/onos/net/topology/DefaultGraphDescriptionTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/topology/DefaultGraphDescriptionTest.java
@@ -16,6 +16,7 @@
 package org.onlab.onos.net.topology;
 
 import com.google.common.collect.ImmutableSet;
+
 import org.junit.Test;
 import org.onlab.onos.net.DefaultDevice;
 import org.onlab.onos.net.Device;
@@ -47,9 +48,13 @@
         assertEquals("incorrect edge count", 2, desc.edges().size());
     }
 
-    @Test(expected = IllegalArgumentException.class)
+    @Test
     public void missingVertex() {
-        new DefaultGraphDescription(4321L, ImmutableSet.of(DEV1, DEV3),
-                                    ImmutableSet.of(L1, L2));
+        GraphDescription desc = new DefaultGraphDescription(4321L,
+                                                            ImmutableSet.of(DEV1, DEV3),
+                                                            ImmutableSet.of(L1, L2));
+        assertEquals("incorrect time", 4321L, desc.timestamp());
+        assertEquals("incorrect vertex count", 2, desc.vertexes().size());
+        assertEquals("incorrect edge count", 0, desc.edges().size());
     }
 }
diff --git a/core/api/src/test/java/org/onlab/onos/net/topology/DefaultTopologyEdgeTest.java b/core/api/src/test/java/org/onlab/onos/net/topology/DefaultTopologyEdgeTest.java
index bf34e1c..9984315 100644
--- a/core/api/src/test/java/org/onlab/onos/net/topology/DefaultTopologyEdgeTest.java
+++ b/core/api/src/test/java/org/onlab/onos/net/topology/DefaultTopologyEdgeTest.java
@@ -48,7 +48,9 @@
 
     static final ProviderId PID = new ProviderId("foo", "bar");
 
+    /** D1:P1 -> D2:P1. */
     static final Link L1 = new DefaultLink(PID, CP1, CP2, Link.Type.INDIRECT);
+    /** D2:P1 -> D1:P2. */
     static final Link L2 = new DefaultLink(PID, CP3, CP4, Link.Type.INDIRECT);
 
     @Test
diff --git a/core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java b/core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java
index a3e0d6c..214fdff 100644
--- a/core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java
+++ b/core/net/src/main/java/org/onlab/onos/net/topology/impl/DefaultTopologyProvider.java
@@ -203,6 +203,7 @@
                 buildTopology(reasons);
             } catch (Exception e) {
                 log.warn("Unable to compute topology due to: {}", e.getMessage());
+                log.debug("Unable to compute topology", e);
             }
         }
     }