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/UiEdgeLinkTest.java b/core/api/src/test/java/org/onosproject/ui/model/topo/UiEdgeLinkTest.java
new file mode 100644
index 0000000..d5b213a
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/ui/model/topo/UiEdgeLinkTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.model.topo;
+
+import org.junit.Test;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultEdgeLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.EdgeLink;
+import org.onosproject.net.PortNumber;
+import org.onosproject.ui.model.AbstractUiModelTest;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Unit tests for {@link UiEdgeLink}.
+ */
+public class UiEdgeLinkTest extends AbstractUiModelTest {
+
+ private static final String PHANTOM_HOST_ID = "00:00:00:00:00:00/None";
+ private static final String D1_P8 = "dev-1/8";
+
+ private static final DeviceId DEV = DeviceId.deviceId("dev-1");
+ private static final PortNumber P8 = PortNumber.portNumber(8);
+ private static final ConnectPoint CP = new ConnectPoint(DEV, P8);
+
+ private static final EdgeLink EDGE_LINK =
+ DefaultEdgeLink.createEdgeLink(CP, true);
+
+ @Test
+ public void basic() {
+ title("basic");
+ UiLinkId id = UiLinkId.uiLinkId(EDGE_LINK);
+ UiEdgeLink link = new UiEdgeLink(null, id);
+ link.attachEdgeLink(EDGE_LINK);
+ print(link);
+ print(link.endPointA());
+ print(link.endPointB());
+
+ assertEquals("bad end point A", PHANTOM_HOST_ID, link.endPointA());
+ assertEquals("bad end point B", D1_P8, link.endPointB());
+ }
+}
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());
+ }
+
}
diff --git a/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionDeviceLinkTest.java b/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionDeviceLinkTest.java
new file mode 100644
index 0000000..3fd70d1
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionDeviceLinkTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.model.topo;
+
+import org.junit.Test;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.region.RegionId;
+import org.onosproject.ui.model.AbstractUiModelTest;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.P0;
+import static org.onosproject.net.region.RegionId.regionId;
+
+/**
+ * Unit tests for {@link UiRegionDeviceLink}.
+ */
+public class UiRegionDeviceLinkTest extends AbstractUiModelTest {
+
+ private static final RegionId R1 = regionId("r1");
+ private static final DeviceId DEV_X = deviceId("device-X");
+
+ @Test
+ public void basic() {
+ title("basic");
+ UiLinkId id = UiLinkId.uiLinkId(R1, DEV_X, P0);
+ UiRegionDeviceLink link = new UiRegionDeviceLink(null, id);
+ print(link);
+ assertEquals("region", R1, link.region());
+ assertEquals("device", DEV_X, link.device());
+ assertEquals("port", P0, link.port());
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionLinkTest.java b/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionLinkTest.java
new file mode 100644
index 0000000..de00bd2
--- /dev/null
+++ b/core/api/src/test/java/org/onosproject/ui/model/topo/UiRegionLinkTest.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2016-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.ui.model.topo;
+
+import org.junit.Test;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.Link;
+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.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.P0;
+import static org.onosproject.net.region.RegionId.regionId;
+
+/**
+ * Unit tests for {@link UiRegionLink}.
+ */
+public class UiRegionLinkTest extends AbstractUiModelTest {
+
+ private static final RegionId R1 = regionId("r1");
+ private static final RegionId R2 = regionId("r2");
+
+ private static final DeviceId DEV_X = deviceId("device-X");
+ private static final DeviceId DEV_Y = deviceId("device-Y");
+
+ private static final ConnectPoint CP_X = new ConnectPoint(DEV_X, P0);
+ private static final ConnectPoint CP_Y = new ConnectPoint(DEV_Y, P0);
+
+ private static final Link LINK_X_TO_Y = DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .src(CP_X)
+ .dst(CP_Y)
+ .type(Link.Type.DIRECT)
+ .build();
+
+
+ @Test(expected = NullPointerException.class)
+ public void nullPointerRegion() {
+ title("nullPointerRegion");
+ new UiRegionLink(null, null);
+ }
+
+ @Test
+ public void regionToRegion() {
+ title("regionToRegion");
+ UiLinkId id = UiLinkId.uiLinkId(R1, R2);
+ UiRegionLink link = new UiRegionLink(null, id);
+ print("link: %s", link);
+ assertEquals("bad first region", R1, link.regionA());
+ assertEquals("bad second region", R2, link.regionB());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void wrongLinkType() {
+ title("wrongLinkType");
+ UiLinkId id = UiLinkId.uiLinkId(LINK_X_TO_Y);
+ new UiRegionLink(null, id);
+ }
+}
diff --git a/core/api/src/test/java/org/onosproject/ui/model/topo/UiTopologyTest.java b/core/api/src/test/java/org/onosproject/ui/model/topo/UiTopologyTest.java
index 17d2de7..5df0a9f 100644
--- a/core/api/src/test/java/org/onosproject/ui/model/topo/UiTopologyTest.java
+++ b/core/api/src/test/java/org/onosproject/ui/model/topo/UiTopologyTest.java
@@ -16,20 +16,165 @@
package org.onosproject.ui.model.topo;
+import org.junit.Before;
import org.junit.Test;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.DefaultLink;
+import org.onosproject.net.DeviceId;
+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.AbstractUiTest;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.onosproject.net.DeviceId.deviceId;
+import static org.onosproject.net.PortNumber.portNumber;
+
/**
* Unit tests for {@link UiTopology}.
*/
public class UiTopologyTest extends AbstractUiTest {
+ private static final DeviceId DEV_X = deviceId("dev-X");
+ private static final DeviceId DEV_Y = deviceId("dev-Y");
+ private static final PortNumber P1 = portNumber(1);
+ private static final PortNumber P2 = portNumber(2);
+
+ private static final String DEV_X_ID = "dev-x/1";
+ private static final String DEV_Y_ID = "dev-y/2";
+
+ private static final ConnectPoint CP_X1 = new ConnectPoint(DEV_X, P1);
+ private static final ConnectPoint CP_Y2 = new ConnectPoint(DEV_Y, P2);
+
+ private static final Link LINK_X1_TO_Y2 = DefaultLink.builder()
+ .providerId(ProviderId.NONE)
+ .src(CP_X1)
+ .dst(CP_Y2)
+ .type(Link.Type.DIRECT)
+ .build();
+
+ private static final UiLinkId DX1_DY2 = UiLinkId.uiLinkId(LINK_X1_TO_Y2);
+
+ private static final RegionId ROOT = UiRegion.NULL_ID;
+ private static final RegionId R1 = RegionId.regionId("R1");
+ private static final RegionId R2 = RegionId.regionId("R2");
+ private static final RegionId R3 = RegionId.regionId("R3");
+
+ private static final String DEV_LINK_CLASS = "UiDeviceLink";
+ private static final String REG_LINK_CLASS = "UiRegionLink";
+ private static final String REG_DEV_LINK_CLASS = "UiRegionDeviceLink";
+
+
private UiTopology topo;
+ private UiDeviceLink devLink;
+
+ private List<RegionId> xBranch;
+ private List<RegionId> yBranch;
+ private UiSynthLink synth;
+
+ @Before
+ public void setUp() {
+ topo = new UiTopology();
+ devLink = new UiDeviceLink(null, DX1_DY2);
+ devLink.attachBackingLink(LINK_X1_TO_Y2);
+ }
@Test
public void basic() {
title("basic");
- topo = new UiTopology();
print(topo);
}
+
+ private List<RegionId> branch(RegionId... ids) {
+ List<RegionId> result = new ArrayList<>(ids.length);
+ Collections.addAll(result, ids);
+ return result;
+ }
+
+ private void verifySynth(RegionId id, String cls, String epA, String epB) {
+ synth = topo.makeSynthLink(devLink, xBranch, yBranch);
+ UiLink ulink = synth.link();
+ print(synth);
+ print("EpA{%s} EpB{%s}", ulink.endPointA(), ulink.endPointB());
+
+ assertEquals("wrong region", id, synth.regionId());
+ assertEquals("wrong link class", cls, ulink.type());
+ assertEquals("wrong EP A", epA, ulink.endPointA());
+ assertEquals("wrong EP B", epB, ulink.endPointB());
+ }
+
+ @Test
+ public void makeSynthDevToDevRoot() {
+ title("makeSynthDevToDevRoot");
+ xBranch = branch(ROOT);
+ yBranch = branch(ROOT);
+ verifySynth(ROOT, DEV_LINK_CLASS, DEV_X_ID, DEV_Y_ID);
+ }
+
+ @Test
+ public void makeSynthDevToDevR1() {
+ title("makeSynthDevToDevR1");
+ xBranch = branch(ROOT, R1);
+ yBranch = branch(ROOT, R1);
+ verifySynth(R1, DEV_LINK_CLASS, DEV_X_ID, DEV_Y_ID);
+ }
+
+ @Test
+ public void makeSynthDevToDevR2() {
+ title("makeSynthDevToDevR2");
+ xBranch = branch(ROOT, R1, R2);
+ yBranch = branch(ROOT, R1, R2);
+ verifySynth(R2, DEV_LINK_CLASS, DEV_X_ID, DEV_Y_ID);
+ }
+
+ @Test
+ public void makeSynthRegToRegRoot() {
+ title("makeSynthRegToRegRoot");
+ xBranch = branch(ROOT, R1);
+ yBranch = branch(ROOT, R2);
+ verifySynth(ROOT, REG_LINK_CLASS, R1.id(), R2.id());
+ }
+
+ @Test
+ public void makeSynthRegToRegR1() {
+ title("makeSynthRegToRegR1");
+ xBranch = branch(ROOT, R1, R2);
+ yBranch = branch(ROOT, R1, R3);
+ verifySynth(R1, REG_LINK_CLASS, R2.id(), R3.id());
+ }
+
+ @Test
+ public void makeSynthRegToDevRoot() {
+ title("makeSynthRegToDevRoot");
+
+ // Note: link is canonicalized to region--device order
+
+ xBranch = branch(ROOT);
+ yBranch = branch(ROOT, R1);
+ verifySynth(ROOT, REG_DEV_LINK_CLASS, R1.id(), DEV_X_ID);
+
+ xBranch = branch(ROOT, R1);
+ yBranch = branch(ROOT);
+ verifySynth(ROOT, REG_DEV_LINK_CLASS, R1.id(), DEV_Y_ID);
+ }
+
+ @Test
+ public void makeSynthRegToDevR3() {
+ title("makeSynthRegToDevR3");
+
+ // Note: link is canonicalized to region--device order
+
+ xBranch = branch(ROOT, R3);
+ yBranch = branch(ROOT, R3, R1);
+ verifySynth(R3, REG_DEV_LINK_CLASS, R1.id(), DEV_X_ID);
+
+ xBranch = branch(ROOT, R3, R1);
+ yBranch = branch(ROOT, R3);
+ verifySynth(R3, REG_DEV_LINK_CLASS, R1.id(), DEV_Y_ID);
+ }
}