ONOS-4971: Synthetic Link Data -- WIP

- Breaking out UiLink to subclasses for device links, host links, region links, region-device links,
    - (soon, also peer links).
- Augmenting UiLinkId to include regions as endpoints.
- Introduced UiSynthLink to encapsulate synthetic links bound to regions.
- Model Cache now computes synthetic links from the underlying link data.
- Added endPointA/B() and type() methods to UiLink.
- Updated topo2CurrentRegion response to include synth-links for the region.

Change-Id: Ifa62a15fbe0a58b134d92278b201fa7a72cbfa83
diff --git a/core/api/src/test/java/org/onosproject/ui/model/topo/UiLinkIdTest.java b/core/api/src/test/java/org/onosproject/ui/model/topo/UiLinkIdTest.java
index e129e26..80666d6 100644
--- a/core/api/src/test/java/org/onosproject/ui/model/topo/UiLinkIdTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/model/topo/UiLinkIdTest.java
@@ -17,17 +17,23 @@
 package org.onosproject.ui.model.topo;
 
 import org.junit.Test;
+import org.onlab.packet.MacAddress;
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.DefaultLink;
 import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
 import org.onosproject.net.Link;
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.provider.ProviderId;
+import org.onosproject.net.region.RegionId;
 import org.onosproject.ui.model.AbstractUiModelTest;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNull;
 import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.HostId.hostId;
+import static org.onosproject.net.PortNumber.P0;
 import static org.onosproject.net.PortNumber.portNumber;
 
 /**
@@ -35,8 +41,15 @@
  */
 public class UiLinkIdTest extends AbstractUiModelTest {
 
+    private static final RegionId REG_1 = RegionId.regionId("Region-1");
+    private static final RegionId REG_2 = RegionId.regionId("Region-2");
+
+    private static final MacAddress MAC_A = MacAddress.valueOf(0x123456L);
+    private static final HostId HOST_A = hostId(MAC_A);
+
     private static final DeviceId DEV_X = deviceId("device-X");
     private static final DeviceId DEV_Y = deviceId("device-Y");
+
     private static final PortNumber P1 = portNumber(1);
     private static final PortNumber P2 = portNumber(2);
     private static final PortNumber P3 = portNumber(3);
@@ -45,6 +58,8 @@
     private static final ConnectPoint CP_Y2 = new ConnectPoint(DEV_Y, P2);
     private static final ConnectPoint CP_Y3 = new ConnectPoint(DEV_Y, P3);
 
+    private static final ConnectPoint CP_HA = new ConnectPoint(HOST_A, P0);
+
     private static final Link LINK_X1_TO_Y2 = DefaultLink.builder()
             .providerId(ProviderId.NONE)
             .src(CP_X1)
@@ -66,6 +81,12 @@
             .type(Link.Type.DIRECT)
             .build();
 
+    private static final Link LINK_HA_TO_X1 = DefaultLink.builder()
+            .providerId(ProviderId.NONE)
+            .src(CP_HA)
+            .dst(CP_X1)
+            .type(Link.Type.EDGE)
+            .build();
 
     @Test
     public void canonical() {
@@ -86,4 +107,61 @@
         print("link other: %s", other);
         assertNotEquals("equiv?", one, other);
     }
+
+    @Test
+    public void edgeLink() {
+        title("edgeLink");
+        UiLinkId id = UiLinkId.uiLinkId(LINK_HA_TO_X1);
+        print("link: %s", id);
+        assertEquals("wrong port A", P0, id.portA());
+        assertEquals("wrong element A", HOST_A, id.elementA());
+        assertEquals("wrong port B", P1, id.portB());
+        assertEquals("wrong element B", DEV_X, id.elementB());
+        assertNull("region A?", id.regionA());
+        assertNull("region B?", id.regionB());
+    }
+
+    @Test
+    public void deviceLink() {
+        title("deviceLink");
+        UiLinkId id = UiLinkId.uiLinkId(LINK_X1_TO_Y2);
+        print("link: %s", id);
+        assertEquals("wrong port A", P1, id.portA());
+        assertEquals("wrong element A", DEV_X, id.elementA());
+        assertEquals("wrong port B", P2, id.portB());
+        assertEquals("wrong element B", DEV_Y, id.elementB());
+        assertNull("region A?", id.regionA());
+        assertNull("region B?", id.regionB());
+    }
+
+    @Test
+    public void regionLink() {
+        title("regionLink");
+        UiLinkId idFirst = UiLinkId.uiLinkId(REG_1, REG_2);
+        UiLinkId idSecond = UiLinkId.uiLinkId(REG_2, REG_1);
+        print(" first: %s", idFirst);
+        print("second: %s", idSecond);
+        assertEquals("Not same ID", idFirst, idSecond);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void identicalRegionBad() {
+        UiLinkId.uiLinkId(REG_1, REG_1);
+    }
+
+    @Test(expected = NullPointerException.class)
+    public void nullRegionBad() {
+        UiLinkId.uiLinkId(REG_1, (RegionId) null);
+    }
+
+    @Test
+    public void regionDeviceLink() {
+        title("regionDeviceLink");
+        UiLinkId id = UiLinkId.uiLinkId(REG_1, DEV_X, P1);
+        print("id: %s", id);
+        assertEquals("region ID", REG_1, id.regionA());
+        assertEquals("device ID", DEV_X, id.elementB());
+        assertEquals("port", P1, id.portB());
+    }
+
 }