Adding port, port number, port description implementations and related tests.
diff --git a/net/api/src/main/java/org/onlab/onos/net/DeviceId.java b/net/api/src/main/java/org/onlab/onos/net/DeviceId.java
index 6f4cff2..19577a1 100644
--- a/net/api/src/main/java/org/onlab/onos/net/DeviceId.java
+++ b/net/api/src/main/java/org/onlab/onos/net/DeviceId.java
@@ -5,16 +5,29 @@
/**
* Immutable representation of a device identity.
*/
-public class DeviceId extends ElementId {
+public final class DeviceId extends ElementId {
- // TODO: Discuss whether we should just use ElementId for Device and Host alike
+ // Public construction is prohibited
+ private DeviceId(URI uri) {
+ super(uri);
+ }
+
/**
* Creates a device id using the supplied URI.
*
- * @param uri backing device URI
+ * @param uri device URI
*/
- public DeviceId(URI uri) {
- super(uri);
+ public static DeviceId deviceId(URI uri) {
+ return new DeviceId(uri);
+ }
+
+ /**
+ * Creates a device id using the supplied URI string.
+ *
+ * @param string device URI string
+ */
+ public static DeviceId deviceId(String string) {
+ return new DeviceId(URI.create(string));
}
}
diff --git a/net/api/src/main/java/org/onlab/onos/net/ElementId.java b/net/api/src/main/java/org/onlab/onos/net/ElementId.java
index e0f3add..9f7dffb 100644
--- a/net/api/src/main/java/org/onlab/onos/net/ElementId.java
+++ b/net/api/src/main/java/org/onlab/onos/net/ElementId.java
@@ -8,7 +8,7 @@
/**
* Immutable representation of a network element identity.
*/
-public class ElementId {
+public abstract class ElementId {
private final URI uri;
@@ -17,7 +17,7 @@
*
* @param uri backing URI
*/
- public ElementId(URI uri) {
+ protected ElementId(URI uri) {
this.uri = uri;
}
@@ -37,14 +37,12 @@
@Override
public boolean equals(Object obj) {
- if (this == obj) {
- return true;
+ if (obj instanceof ElementId) {
+ final ElementId that = (ElementId) obj;
+ return this.getClass() == that.getClass() &&
+ Objects.equals(this.uri, that.uri);
}
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- final ElementId other = (ElementId) obj;
- return Objects.equals(this.uri, other.uri);
+ return false;
}
@Override
diff --git a/net/api/src/main/java/org/onlab/onos/net/Port.java b/net/api/src/main/java/org/onlab/onos/net/Port.java
index 3135b77..24fd533 100644
--- a/net/api/src/main/java/org/onlab/onos/net/Port.java
+++ b/net/api/src/main/java/org/onlab/onos/net/Port.java
@@ -1,11 +1,18 @@
package org.onlab.onos.net;
+import java.util.Set;
+
/**
* Abstraction of a network port.
*/
public interface Port {
- // Notion of port state: enabled, disabled, blocked
+ /**
+ * Port state.
+ */
+ enum State {
+ UP, DOWN, BLOCKED, UNKNOWN
+ }
/**
* Returns the port number.
@@ -15,6 +22,27 @@
PortNumber number();
/**
+ * Returns the port state(s).
+ *
+ * @return port state set
+ */
+ Set<State> state();
+
+ /**
+ * Indicates whether or not the port is currently up and active.
+ *
+ * @return true if the port is operational
+ */
+ boolean isEnabled();
+
+ /**
+ * Indicates whether or not the port is administratively blocked.
+ *
+ * @return true if the port is blocked
+ */
+ boolean isBlocked();
+
+ /**
* Returns the identifier of the network element to which this port belongs.
*
* @return parent network element
diff --git a/net/api/src/main/java/org/onlab/onos/net/PortNumber.java b/net/api/src/main/java/org/onlab/onos/net/PortNumber.java
index 4ea4e24..45ee9ee 100644
--- a/net/api/src/main/java/org/onlab/onos/net/PortNumber.java
+++ b/net/api/src/main/java/org/onlab/onos/net/PortNumber.java
@@ -1,7 +1,73 @@
package org.onlab.onos.net;
+import com.google.common.primitives.UnsignedLongs;
+
+import java.util.Objects;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
/**
* Representation of a port number.
*/
-public interface PortNumber {
+public final class PortNumber {
+
+ private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
+
+ private final long number;
+
+ // Public creation is prohibited
+ private PortNumber(long number) {
+ checkArgument(number >= 0 && number < MAX_NUMBER,
+ "Port number %d is outside the supported range [0, %d)",
+ number, MAX_NUMBER);
+ this.number = number;
+ }
+
+ /**
+ * Returns the port number representing the specified long value.
+ *
+ * @param number port number as long value
+ * @return port number
+ */
+ public static PortNumber portNumber(long number) {
+ return new PortNumber(number);
+ }
+
+ /**
+ * Returns the port number representing the specified string value.
+ *
+ * @param string port number as string value
+ * @return port number
+ */
+ public static PortNumber portNumber(String string) {
+ return new PortNumber(UnsignedLongs.decode(string));
+ }
+
+ /**
+ * Returns the backing long value.
+ *
+ * @return port number as long
+ */
+ public long toLong() {
+ return number;
+ }
+
+ @Override
+ public String toString() {
+ return UnsignedLongs.toString(number);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(number);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj instanceof PortNumber) {
+ final PortNumber other = (PortNumber) obj;
+ return this.number == other.number;
+ }
+ return false;
+ }
}
diff --git a/net/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java b/net/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
index c171098..c434ff5 100644
--- a/net/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
+++ b/net/api/src/main/java/org/onlab/onos/net/device/DefaultPortDescription.java
@@ -1,7 +1,32 @@
package org.onlab.onos.net.device;
+import com.google.common.collect.ImmutableSet;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
+
+import java.util.Set;
+
/**
* Default implementation of immutable port description.
*/
public class DefaultPortDescription implements PortDescription {
+
+ private final PortNumber number;
+ private final Set<Port.State> state;
+
+ public DefaultPortDescription(PortNumber number, Set<Port.State> state) {
+ this.number = number;
+ this.state = ImmutableSet.copyOf(state);
+ }
+
+ @Override
+ public PortNumber portNumber() {
+ return number;
+ }
+
+ @Override
+ public Set<Port.State> portState() {
+ return state;
+ }
+
}
diff --git a/net/api/src/main/java/org/onlab/onos/net/device/PortDescription.java b/net/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
index 4c944ab..2f86248 100644
--- a/net/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
+++ b/net/api/src/main/java/org/onlab/onos/net/device/PortDescription.java
@@ -1,5 +1,10 @@
package org.onlab.onos.net.device;
+import org.onlab.onos.net.Port;
+import org.onlab.onos.net.PortNumber;
+
+import java.util.Set;
+
/**
* Information about a port.
*/
@@ -7,4 +12,18 @@
// TODO: possibly relocate this to a common ground so that this can also used by host tracking if required
+ /**
+ * Returns the port number.
+ *
+ * @return port number
+ */
+ PortNumber portNumber();
+
+ /**
+ * Returns the port state set.
+ *
+ * @return set of port states
+ */
+ Set<Port.State> portState();
+
}
diff --git a/net/api/src/test/java/org/onlab/onos/event/AbstractEventTest.java b/net/api/src/test/java/org/onlab/onos/event/AbstractEventTest.java
index 5ec3669..b79b836 100644
--- a/net/api/src/test/java/org/onlab/onos/event/AbstractEventTest.java
+++ b/net/api/src/test/java/org/onlab/onos/event/AbstractEventTest.java
@@ -11,12 +11,46 @@
*/
public class AbstractEventTest {
+ /**
+ * Validates the base attributes of an event.
+ *
+ * @param event event to validate
+ * @param type event type
+ * @param subject event subject
+ * @param time event time
+ * @param <T> type of event
+ * @param <S> type of subject
+ */
+ protected static <T extends Enum, S>
+ void validateEvent(Event<T, S> event, T type, S subject, long time) {
+ assertEquals("incorrect type", type, event.type());
+ assertEquals("incorrect subject", subject, event.subject());
+ assertEquals("incorrect time", time, event.time());
+ }
+
+ /**
+ * Validates the base attributes of an event.
+ *
+ * @param event event to validate
+ * @param type event type
+ * @param subject event subject
+ * @param minTime minimum event time inclusive
+ * @param maxTime maximum event time inclusive
+ * @param <T> type of event
+ * @param <S> type of subject
+ */
+ protected static <T extends Enum, S>
+ void validateEvent(Event<T, S> event, T type, S subject,
+ long minTime, long maxTime) {
+ assertEquals("incorrect type", type, event.type());
+ assertEquals("incorrect subject", subject, event.subject());
+ assertTrue("incorrect time", minTime <= event.time() && event.time() <= maxTime);
+ }
+
@Test
public void withTime() {
TestEvent event = new TestEvent(FOO, "foo", 123L);
- assertEquals("incorrect type", FOO, event.type());
- assertEquals("incorrect subject", "foo", event.subject());
- assertEquals("incorrect time", 123L, event.time());
+ validateEvent(event, FOO, "foo", 123L);
}
@Test
@@ -24,8 +58,7 @@
long before = System.currentTimeMillis();
TestEvent event = new TestEvent(FOO, "foo");
long after = System.currentTimeMillis();
- assertEquals("incorrect type", FOO, event.type());
- assertEquals("incorrect subject", "foo", event.subject());
- assertTrue("incorrect time", before <= event.time() && event.time() <= after);
+ validateEvent(event, FOO, "foo", before, after);
}
+
}
diff --git a/net/api/src/test/java/org/onlab/onos/net/DefaultDeviceTest.java b/net/api/src/test/java/org/onlab/onos/net/DefaultDeviceTest.java
index 1d174ca..c37a15c 100644
--- a/net/api/src/test/java/org/onlab/onos/net/DefaultDeviceTest.java
+++ b/net/api/src/test/java/org/onlab/onos/net/DefaultDeviceTest.java
@@ -4,10 +4,9 @@
import org.junit.Test;
import org.onlab.onos.net.provider.ProviderId;
-import java.net.URI;
-
import static org.junit.Assert.assertEquals;
import static org.onlab.onos.net.Device.Type.SWITCH;
+import static org.onlab.onos.net.DeviceId.deviceId;
/**
* Test of the default device model entity.
@@ -15,8 +14,8 @@
public class DefaultDeviceTest {
private static final ProviderId PID = new ProviderId("foo");
- private static final DeviceId DID1 = new DeviceId(URI.create("of:foo"));
- private static final DeviceId DID2 = new DeviceId(URI.create("of:bar"));
+ private static final DeviceId DID1 = deviceId("of:foo");
+ private static final DeviceId DID2 = deviceId("of:bar");
private static final String MFR = "whitebox";
private static final String HW = "1.1.x";
private static final String SW = "3.9.1";
diff --git a/net/api/src/test/java/org/onlab/onos/net/DeviceIdTest.java b/net/api/src/test/java/org/onlab/onos/net/DeviceIdTest.java
index f373678..eaee54c 100644
--- a/net/api/src/test/java/org/onlab/onos/net/DeviceIdTest.java
+++ b/net/api/src/test/java/org/onlab/onos/net/DeviceIdTest.java
@@ -3,17 +3,19 @@
import com.google.common.testing.EqualsTester;
import org.junit.Test;
+import static org.onlab.onos.net.DeviceId.deviceId;
+
/**
- * Test of the provider identifier.
+ * Test of the device identifier.
*/
public class DeviceIdTest extends ElementIdTest {
@Test
public void basics() {
new EqualsTester()
- .addEqualityGroup(new DeviceId(uri("of:foo")),
- new DeviceId(uri("of:foo")))
- .addEqualityGroup(new DeviceId(uri("of:bar")))
+ .addEqualityGroup(deviceId("of:foo"),
+ deviceId("of:foo"))
+ .addEqualityGroup(deviceId("of:bar"))
.testEquals();
}
diff --git a/net/api/src/test/java/org/onlab/onos/net/ElementIdTest.java b/net/api/src/test/java/org/onlab/onos/net/ElementIdTest.java
index 4de68dd..cf209b3 100644
--- a/net/api/src/test/java/org/onlab/onos/net/ElementIdTest.java
+++ b/net/api/src/test/java/org/onlab/onos/net/ElementIdTest.java
@@ -8,10 +8,16 @@
import static org.junit.Assert.assertEquals;
/**
- * Test of the provider identifier.
+ * Test of the network element identifier.
*/
public class ElementIdTest {
+ private static class FooId extends ElementId {
+ public FooId(URI uri) {
+ super(uri);
+ }
+ }
+
public static URI uri(String str) {
return URI.create(str);
}
@@ -19,12 +25,12 @@
@Test
public void basics() {
new EqualsTester()
- .addEqualityGroup(new ElementId(uri("of:foo")),
- new ElementId(uri("of:foo")))
- .addEqualityGroup(new ElementId(uri("of:bar")))
+ .addEqualityGroup(new FooId(uri("of:foo")),
+ new FooId(uri("of:foo")))
+ .addEqualityGroup(new FooId(uri("of:bar")))
.testEquals();
assertEquals("wrong uri", uri("ofcfg:foo"),
- new ElementId(uri("ofcfg:foo")).uri());
+ new FooId(uri("ofcfg:foo")).uri());
}
}
diff --git a/net/api/src/test/java/org/onlab/onos/net/PortNumberTest.java b/net/api/src/test/java/org/onlab/onos/net/PortNumberTest.java
new file mode 100644
index 0000000..fced985
--- /dev/null
+++ b/net/api/src/test/java/org/onlab/onos/net/PortNumberTest.java
@@ -0,0 +1,37 @@
+package org.onlab.onos.net;
+
+import com.google.common.testing.EqualsTester;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.onlab.onos.net.PortNumber.portNumber;
+
+/**
+ * Test of the port number.
+ */
+public class PortNumberTest extends ElementIdTest {
+
+ @Test
+ public void basics() {
+ new EqualsTester()
+ .addEqualityGroup(portNumber(123),
+ portNumber("123"))
+ .addEqualityGroup(portNumber(321))
+ .testEquals();
+ }
+
+ @Test
+ public void number() {
+ assertEquals("incorrect long value", 12345, portNumber(12345).toLong());
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void negative() {
+ portNumber(-1);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void tooBig() {
+ portNumber((2L * Integer.MAX_VALUE) + 2);
+ }
+}
diff --git a/net/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java b/net/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java
new file mode 100644
index 0000000..df2b419
--- /dev/null
+++ b/net/api/src/test/java/org/onlab/onos/net/device/DeviceEventTest.java
@@ -0,0 +1,39 @@
+package org.onlab.onos.net.device;
+
+import org.junit.Test;
+import org.onlab.onos.event.AbstractEventTest;
+import org.onlab.onos.net.DefaultDevice;
+import org.onlab.onos.net.Device;
+import org.onlab.onos.net.provider.ProviderId;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+
+/**
+ * Tests of the device event.
+ */
+public class DeviceEventTest extends AbstractEventTest {
+
+ private Device createDevice() {
+ return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"),
+ Device.Type.SWITCH, "box", "hw", "sw", "sn");
+ }
+
+ @Test
+ public void withTime() {
+ Device device = createDevice();
+ DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
+ device, 123L);
+ validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L);
+ }
+
+ @Test
+ public void withoutTime() {
+ Device device = createDevice();
+ long before = System.currentTimeMillis();
+ DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
+ device);
+ long after = System.currentTimeMillis();
+ validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, before, after);
+ }
+
+}
diff --git a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
index ad4ccad..81d05f6 100644
--- a/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/providers/of/device/src/main/java/org/onlab/onos/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -1,17 +1,11 @@
package org.onlab.onos.provider.of.device.impl;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.net.Device;
-import org.onlab.onos.net.DeviceId;
import org.onlab.onos.net.MastershipRole;
import org.onlab.onos.net.device.DefaultDeviceDescription;
import org.onlab.onos.net.device.DeviceDescription;
@@ -27,6 +21,12 @@
import org.onlab.onos.of.controller.RoleState;
import org.slf4j.Logger;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+import static org.onlab.onos.net.DeviceId.deviceId;
+import static org.slf4j.LoggerFactory.getLogger;
+
/**
* Provider which uses an OpenFlow controller to detect network
* infrastructure devices.
@@ -73,19 +73,19 @@
@Override
public void roleChanged(Device device, MastershipRole newRole) {
switch (newRole) {
- case MASTER:
- controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
- RoleState.MASTER);
- break;
- case STANDBY:
- controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
- RoleState.EQUAL);
- case NONE:
- controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
- RoleState.SLAVE);
- break;
- default:
- log.error("Unknown Mastership state : {}", newRole);
+ case MASTER:
+ controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+ RoleState.MASTER);
+ break;
+ case STANDBY:
+ controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+ RoleState.EQUAL);
+ case NONE:
+ controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
+ RoleState.SLAVE);
+ break;
+ default:
+ log.error("Unknown Mastership state : {}", newRole);
}
log.info("Accepting mastership role change for device {}", device.id());
@@ -102,11 +102,11 @@
DeviceDescription description =
new DefaultDeviceDescription(buildURI(dpid), Device.Type.SWITCH,
- sw.manfacturerDescription(),
- sw.hardwareDescription(),
- sw.softwareDescription(),
- sw.softwareDescription());
- providerService.deviceConnected(new DeviceId(uri), description);
+ sw.manfacturerDescription(),
+ sw.hardwareDescription(),
+ sw.softwareDescription(),
+ sw.softwareDescription());
+ providerService.deviceConnected(deviceId(uri), description);
}
@Override
@@ -115,7 +115,7 @@
return;
}
URI uri = buildURI(dpid);
- providerService.deviceDisconnected(new DeviceId(uri));
+ providerService.deviceDisconnected(deviceId(uri));
}
private URI buildURI(Dpid dpid) {