tom

Adding port, port number, port description implementations and related tests.

...@@ -5,16 +5,29 @@ import java.net.URI; ...@@ -5,16 +5,29 @@ import java.net.URI;
5 /** 5 /**
6 * Immutable representation of a device identity. 6 * Immutable representation of a device identity.
7 */ 7 */
8 -public class DeviceId extends ElementId { 8 +public final class DeviceId extends ElementId {
9 +
10 + // Public construction is prohibited
11 + private DeviceId(URI uri) {
12 + super(uri);
13 + }
9 14
10 - // TODO: Discuss whether we should just use ElementId for Device and Host alike
11 /** 15 /**
12 * Creates a device id using the supplied URI. 16 * Creates a device id using the supplied URI.
13 * 17 *
14 - * @param uri backing device URI 18 + * @param uri device URI
15 */ 19 */
16 - public DeviceId(URI uri) { 20 + public static DeviceId deviceId(URI uri) {
17 - super(uri); 21 + return new DeviceId(uri);
22 + }
23 +
24 + /**
25 + * Creates a device id using the supplied URI string.
26 + *
27 + * @param string device URI string
28 + */
29 + public static DeviceId deviceId(String string) {
30 + return new DeviceId(URI.create(string));
18 } 31 }
19 32
20 } 33 }
......
...@@ -8,7 +8,7 @@ import static com.google.common.base.Objects.toStringHelper; ...@@ -8,7 +8,7 @@ import static com.google.common.base.Objects.toStringHelper;
8 /** 8 /**
9 * Immutable representation of a network element identity. 9 * Immutable representation of a network element identity.
10 */ 10 */
11 -public class ElementId { 11 +public abstract class ElementId {
12 12
13 private final URI uri; 13 private final URI uri;
14 14
...@@ -17,7 +17,7 @@ public class ElementId { ...@@ -17,7 +17,7 @@ public class ElementId {
17 * 17 *
18 * @param uri backing URI 18 * @param uri backing URI
19 */ 19 */
20 - public ElementId(URI uri) { 20 + protected ElementId(URI uri) {
21 this.uri = uri; 21 this.uri = uri;
22 } 22 }
23 23
...@@ -37,14 +37,12 @@ public class ElementId { ...@@ -37,14 +37,12 @@ public class ElementId {
37 37
38 @Override 38 @Override
39 public boolean equals(Object obj) { 39 public boolean equals(Object obj) {
40 - if (this == obj) { 40 + if (obj instanceof ElementId) {
41 - return true; 41 + final ElementId that = (ElementId) obj;
42 + return this.getClass() == that.getClass() &&
43 + Objects.equals(this.uri, that.uri);
42 } 44 }
43 - if (obj == null || getClass() != obj.getClass()) { 45 + return false;
44 - return false;
45 - }
46 - final ElementId other = (ElementId) obj;
47 - return Objects.equals(this.uri, other.uri);
48 } 46 }
49 47
50 @Override 48 @Override
......
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 +import java.util.Set;
4 +
3 /** 5 /**
4 * Abstraction of a network port. 6 * Abstraction of a network port.
5 */ 7 */
6 public interface Port { 8 public interface Port {
7 9
8 - // Notion of port state: enabled, disabled, blocked 10 + /**
11 + * Port state.
12 + */
13 + enum State {
14 + UP, DOWN, BLOCKED, UNKNOWN
15 + }
9 16
10 /** 17 /**
11 * Returns the port number. 18 * Returns the port number.
...@@ -15,6 +22,27 @@ public interface Port { ...@@ -15,6 +22,27 @@ public interface Port {
15 PortNumber number(); 22 PortNumber number();
16 23
17 /** 24 /**
25 + * Returns the port state(s).
26 + *
27 + * @return port state set
28 + */
29 + Set<State> state();
30 +
31 + /**
32 + * Indicates whether or not the port is currently up and active.
33 + *
34 + * @return true if the port is operational
35 + */
36 + boolean isEnabled();
37 +
38 + /**
39 + * Indicates whether or not the port is administratively blocked.
40 + *
41 + * @return true if the port is blocked
42 + */
43 + boolean isBlocked();
44 +
45 + /**
18 * Returns the identifier of the network element to which this port belongs. 46 * Returns the identifier of the network element to which this port belongs.
19 * 47 *
20 * @return parent network element 48 * @return parent network element
......
1 package org.onlab.onos.net; 1 package org.onlab.onos.net;
2 2
3 +import com.google.common.primitives.UnsignedLongs;
4 +
5 +import java.util.Objects;
6 +
7 +import static com.google.common.base.Preconditions.checkArgument;
8 +
3 /** 9 /**
4 * Representation of a port number. 10 * Representation of a port number.
5 */ 11 */
6 -public interface PortNumber { 12 +public final class PortNumber {
13 +
14 + private static final long MAX_NUMBER = (2L * Integer.MAX_VALUE) + 1;
15 +
16 + private final long number;
17 +
18 + // Public creation is prohibited
19 + private PortNumber(long number) {
20 + checkArgument(number >= 0 && number < MAX_NUMBER,
21 + "Port number %d is outside the supported range [0, %d)",
22 + number, MAX_NUMBER);
23 + this.number = number;
24 + }
25 +
26 + /**
27 + * Returns the port number representing the specified long value.
28 + *
29 + * @param number port number as long value
30 + * @return port number
31 + */
32 + public static PortNumber portNumber(long number) {
33 + return new PortNumber(number);
34 + }
35 +
36 + /**
37 + * Returns the port number representing the specified string value.
38 + *
39 + * @param string port number as string value
40 + * @return port number
41 + */
42 + public static PortNumber portNumber(String string) {
43 + return new PortNumber(UnsignedLongs.decode(string));
44 + }
45 +
46 + /**
47 + * Returns the backing long value.
48 + *
49 + * @return port number as long
50 + */
51 + public long toLong() {
52 + return number;
53 + }
54 +
55 + @Override
56 + public String toString() {
57 + return UnsignedLongs.toString(number);
58 + }
59 +
60 + @Override
61 + public int hashCode() {
62 + return Objects.hash(number);
63 + }
64 +
65 + @Override
66 + public boolean equals(Object obj) {
67 + if (obj instanceof PortNumber) {
68 + final PortNumber other = (PortNumber) obj;
69 + return this.number == other.number;
70 + }
71 + return false;
72 + }
7 } 73 }
......
1 package org.onlab.onos.net.device; 1 package org.onlab.onos.net.device;
2 2
3 +import com.google.common.collect.ImmutableSet;
4 +import org.onlab.onos.net.Port;
5 +import org.onlab.onos.net.PortNumber;
6 +
7 +import java.util.Set;
8 +
3 /** 9 /**
4 * Default implementation of immutable port description. 10 * Default implementation of immutable port description.
5 */ 11 */
6 public class DefaultPortDescription implements PortDescription { 12 public class DefaultPortDescription implements PortDescription {
13 +
14 + private final PortNumber number;
15 + private final Set<Port.State> state;
16 +
17 + public DefaultPortDescription(PortNumber number, Set<Port.State> state) {
18 + this.number = number;
19 + this.state = ImmutableSet.copyOf(state);
20 + }
21 +
22 + @Override
23 + public PortNumber portNumber() {
24 + return number;
25 + }
26 +
27 + @Override
28 + public Set<Port.State> portState() {
29 + return state;
30 + }
31 +
7 } 32 }
......
1 package org.onlab.onos.net.device; 1 package org.onlab.onos.net.device;
2 2
3 +import org.onlab.onos.net.Port;
4 +import org.onlab.onos.net.PortNumber;
5 +
6 +import java.util.Set;
7 +
3 /** 8 /**
4 * Information about a port. 9 * Information about a port.
5 */ 10 */
...@@ -7,4 +12,18 @@ public interface PortDescription { ...@@ -7,4 +12,18 @@ public interface PortDescription {
7 12
8 // TODO: possibly relocate this to a common ground so that this can also used by host tracking if required 13 // TODO: possibly relocate this to a common ground so that this can also used by host tracking if required
9 14
15 + /**
16 + * Returns the port number.
17 + *
18 + * @return port number
19 + */
20 + PortNumber portNumber();
21 +
22 + /**
23 + * Returns the port state set.
24 + *
25 + * @return set of port states
26 + */
27 + Set<Port.State> portState();
28 +
10 } 29 }
......
...@@ -11,12 +11,46 @@ import static org.onlab.onos.event.TestEvent.Type.FOO; ...@@ -11,12 +11,46 @@ import static org.onlab.onos.event.TestEvent.Type.FOO;
11 */ 11 */
12 public class AbstractEventTest { 12 public class AbstractEventTest {
13 13
14 + /**
15 + * Validates the base attributes of an event.
16 + *
17 + * @param event event to validate
18 + * @param type event type
19 + * @param subject event subject
20 + * @param time event time
21 + * @param <T> type of event
22 + * @param <S> type of subject
23 + */
24 + protected static <T extends Enum, S>
25 + void validateEvent(Event<T, S> event, T type, S subject, long time) {
26 + assertEquals("incorrect type", type, event.type());
27 + assertEquals("incorrect subject", subject, event.subject());
28 + assertEquals("incorrect time", time, event.time());
29 + }
30 +
31 + /**
32 + * Validates the base attributes of an event.
33 + *
34 + * @param event event to validate
35 + * @param type event type
36 + * @param subject event subject
37 + * @param minTime minimum event time inclusive
38 + * @param maxTime maximum event time inclusive
39 + * @param <T> type of event
40 + * @param <S> type of subject
41 + */
42 + protected static <T extends Enum, S>
43 + void validateEvent(Event<T, S> event, T type, S subject,
44 + long minTime, long maxTime) {
45 + assertEquals("incorrect type", type, event.type());
46 + assertEquals("incorrect subject", subject, event.subject());
47 + assertTrue("incorrect time", minTime <= event.time() && event.time() <= maxTime);
48 + }
49 +
14 @Test 50 @Test
15 public void withTime() { 51 public void withTime() {
16 TestEvent event = new TestEvent(FOO, "foo", 123L); 52 TestEvent event = new TestEvent(FOO, "foo", 123L);
17 - assertEquals("incorrect type", FOO, event.type()); 53 + validateEvent(event, FOO, "foo", 123L);
18 - assertEquals("incorrect subject", "foo", event.subject());
19 - assertEquals("incorrect time", 123L, event.time());
20 } 54 }
21 55
22 @Test 56 @Test
...@@ -24,8 +58,7 @@ public class AbstractEventTest { ...@@ -24,8 +58,7 @@ public class AbstractEventTest {
24 long before = System.currentTimeMillis(); 58 long before = System.currentTimeMillis();
25 TestEvent event = new TestEvent(FOO, "foo"); 59 TestEvent event = new TestEvent(FOO, "foo");
26 long after = System.currentTimeMillis(); 60 long after = System.currentTimeMillis();
27 - assertEquals("incorrect type", FOO, event.type()); 61 + validateEvent(event, FOO, "foo", before, after);
28 - assertEquals("incorrect subject", "foo", event.subject());
29 - assertTrue("incorrect time", before <= event.time() && event.time() <= after);
30 } 62 }
63 +
31 } 64 }
......
...@@ -4,10 +4,9 @@ import com.google.common.testing.EqualsTester; ...@@ -4,10 +4,9 @@ import com.google.common.testing.EqualsTester;
4 import org.junit.Test; 4 import org.junit.Test;
5 import org.onlab.onos.net.provider.ProviderId; 5 import org.onlab.onos.net.provider.ProviderId;
6 6
7 -import java.net.URI;
8 -
9 import static org.junit.Assert.assertEquals; 7 import static org.junit.Assert.assertEquals;
10 import static org.onlab.onos.net.Device.Type.SWITCH; 8 import static org.onlab.onos.net.Device.Type.SWITCH;
9 +import static org.onlab.onos.net.DeviceId.deviceId;
11 10
12 /** 11 /**
13 * Test of the default device model entity. 12 * Test of the default device model entity.
...@@ -15,8 +14,8 @@ import static org.onlab.onos.net.Device.Type.SWITCH; ...@@ -15,8 +14,8 @@ import static org.onlab.onos.net.Device.Type.SWITCH;
15 public class DefaultDeviceTest { 14 public class DefaultDeviceTest {
16 15
17 private static final ProviderId PID = new ProviderId("foo"); 16 private static final ProviderId PID = new ProviderId("foo");
18 - private static final DeviceId DID1 = new DeviceId(URI.create("of:foo")); 17 + private static final DeviceId DID1 = deviceId("of:foo");
19 - private static final DeviceId DID2 = new DeviceId(URI.create("of:bar")); 18 + private static final DeviceId DID2 = deviceId("of:bar");
20 private static final String MFR = "whitebox"; 19 private static final String MFR = "whitebox";
21 private static final String HW = "1.1.x"; 20 private static final String HW = "1.1.x";
22 private static final String SW = "3.9.1"; 21 private static final String SW = "3.9.1";
......
...@@ -3,17 +3,19 @@ package org.onlab.onos.net; ...@@ -3,17 +3,19 @@ package org.onlab.onos.net;
3 import com.google.common.testing.EqualsTester; 3 import com.google.common.testing.EqualsTester;
4 import org.junit.Test; 4 import org.junit.Test;
5 5
6 +import static org.onlab.onos.net.DeviceId.deviceId;
7 +
6 /** 8 /**
7 - * Test of the provider identifier. 9 + * Test of the device identifier.
8 */ 10 */
9 public class DeviceIdTest extends ElementIdTest { 11 public class DeviceIdTest extends ElementIdTest {
10 12
11 @Test 13 @Test
12 public void basics() { 14 public void basics() {
13 new EqualsTester() 15 new EqualsTester()
14 - .addEqualityGroup(new DeviceId(uri("of:foo")), 16 + .addEqualityGroup(deviceId("of:foo"),
15 - new DeviceId(uri("of:foo"))) 17 + deviceId("of:foo"))
16 - .addEqualityGroup(new DeviceId(uri("of:bar"))) 18 + .addEqualityGroup(deviceId("of:bar"))
17 .testEquals(); 19 .testEquals();
18 } 20 }
19 21
......
...@@ -8,10 +8,16 @@ import java.net.URI; ...@@ -8,10 +8,16 @@ import java.net.URI;
8 import static org.junit.Assert.assertEquals; 8 import static org.junit.Assert.assertEquals;
9 9
10 /** 10 /**
11 - * Test of the provider identifier. 11 + * Test of the network element identifier.
12 */ 12 */
13 public class ElementIdTest { 13 public class ElementIdTest {
14 14
15 + private static class FooId extends ElementId {
16 + public FooId(URI uri) {
17 + super(uri);
18 + }
19 + }
20 +
15 public static URI uri(String str) { 21 public static URI uri(String str) {
16 return URI.create(str); 22 return URI.create(str);
17 } 23 }
...@@ -19,12 +25,12 @@ public class ElementIdTest { ...@@ -19,12 +25,12 @@ public class ElementIdTest {
19 @Test 25 @Test
20 public void basics() { 26 public void basics() {
21 new EqualsTester() 27 new EqualsTester()
22 - .addEqualityGroup(new ElementId(uri("of:foo")), 28 + .addEqualityGroup(new FooId(uri("of:foo")),
23 - new ElementId(uri("of:foo"))) 29 + new FooId(uri("of:foo")))
24 - .addEqualityGroup(new ElementId(uri("of:bar"))) 30 + .addEqualityGroup(new FooId(uri("of:bar")))
25 .testEquals(); 31 .testEquals();
26 assertEquals("wrong uri", uri("ofcfg:foo"), 32 assertEquals("wrong uri", uri("ofcfg:foo"),
27 - new ElementId(uri("ofcfg:foo")).uri()); 33 + new FooId(uri("ofcfg:foo")).uri());
28 } 34 }
29 35
30 } 36 }
......
1 +package org.onlab.onos.net;
2 +
3 +import com.google.common.testing.EqualsTester;
4 +import org.junit.Test;
5 +
6 +import static org.junit.Assert.assertEquals;
7 +import static org.onlab.onos.net.PortNumber.portNumber;
8 +
9 +/**
10 + * Test of the port number.
11 + */
12 +public class PortNumberTest extends ElementIdTest {
13 +
14 + @Test
15 + public void basics() {
16 + new EqualsTester()
17 + .addEqualityGroup(portNumber(123),
18 + portNumber("123"))
19 + .addEqualityGroup(portNumber(321))
20 + .testEquals();
21 + }
22 +
23 + @Test
24 + public void number() {
25 + assertEquals("incorrect long value", 12345, portNumber(12345).toLong());
26 + }
27 +
28 + @Test(expected = IllegalArgumentException.class)
29 + public void negative() {
30 + portNumber(-1);
31 + }
32 +
33 + @Test(expected = IllegalArgumentException.class)
34 + public void tooBig() {
35 + portNumber((2L * Integer.MAX_VALUE) + 2);
36 + }
37 +}
1 +package org.onlab.onos.net.device;
2 +
3 +import org.junit.Test;
4 +import org.onlab.onos.event.AbstractEventTest;
5 +import org.onlab.onos.net.DefaultDevice;
6 +import org.onlab.onos.net.Device;
7 +import org.onlab.onos.net.provider.ProviderId;
8 +
9 +import static org.onlab.onos.net.DeviceId.deviceId;
10 +
11 +/**
12 + * Tests of the device event.
13 + */
14 +public class DeviceEventTest extends AbstractEventTest {
15 +
16 + private Device createDevice() {
17 + return new DefaultDevice(new ProviderId("foo"), deviceId("of:foo"),
18 + Device.Type.SWITCH, "box", "hw", "sw", "sn");
19 + }
20 +
21 + @Test
22 + public void withTime() {
23 + Device device = createDevice();
24 + DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
25 + device, 123L);
26 + validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L);
27 + }
28 +
29 + @Test
30 + public void withoutTime() {
31 + Device device = createDevice();
32 + long before = System.currentTimeMillis();
33 + DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
34 + device);
35 + long after = System.currentTimeMillis();
36 + validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, before, after);
37 + }
38 +
39 +}
1 package org.onlab.onos.provider.of.device.impl; 1 package org.onlab.onos.provider.of.device.impl;
2 2
3 -import static org.slf4j.LoggerFactory.getLogger;
4 -
5 -import java.net.URI;
6 -import java.net.URISyntaxException;
7 -
8 import org.apache.felix.scr.annotations.Activate; 3 import org.apache.felix.scr.annotations.Activate;
9 import org.apache.felix.scr.annotations.Component; 4 import org.apache.felix.scr.annotations.Component;
10 import org.apache.felix.scr.annotations.Deactivate; 5 import org.apache.felix.scr.annotations.Deactivate;
11 import org.apache.felix.scr.annotations.Reference; 6 import org.apache.felix.scr.annotations.Reference;
12 import org.apache.felix.scr.annotations.ReferenceCardinality; 7 import org.apache.felix.scr.annotations.ReferenceCardinality;
13 import org.onlab.onos.net.Device; 8 import org.onlab.onos.net.Device;
14 -import org.onlab.onos.net.DeviceId;
15 import org.onlab.onos.net.MastershipRole; 9 import org.onlab.onos.net.MastershipRole;
16 import org.onlab.onos.net.device.DefaultDeviceDescription; 10 import org.onlab.onos.net.device.DefaultDeviceDescription;
17 import org.onlab.onos.net.device.DeviceDescription; 11 import org.onlab.onos.net.device.DeviceDescription;
...@@ -27,6 +21,12 @@ import org.onlab.onos.of.controller.OpenFlowSwitchListener; ...@@ -27,6 +21,12 @@ import org.onlab.onos.of.controller.OpenFlowSwitchListener;
27 import org.onlab.onos.of.controller.RoleState; 21 import org.onlab.onos.of.controller.RoleState;
28 import org.slf4j.Logger; 22 import org.slf4j.Logger;
29 23
24 +import java.net.URI;
25 +import java.net.URISyntaxException;
26 +
27 +import static org.onlab.onos.net.DeviceId.deviceId;
28 +import static org.slf4j.LoggerFactory.getLogger;
29 +
30 /** 30 /**
31 * Provider which uses an OpenFlow controller to detect network 31 * Provider which uses an OpenFlow controller to detect network
32 * infrastructure devices. 32 * infrastructure devices.
...@@ -73,19 +73,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -73,19 +73,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
73 @Override 73 @Override
74 public void roleChanged(Device device, MastershipRole newRole) { 74 public void roleChanged(Device device, MastershipRole newRole) {
75 switch (newRole) { 75 switch (newRole) {
76 - case MASTER: 76 + case MASTER:
77 - controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()), 77 + controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
78 - RoleState.MASTER); 78 + RoleState.MASTER);
79 - break; 79 + break;
80 - case STANDBY: 80 + case STANDBY:
81 - controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()), 81 + controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
82 - RoleState.EQUAL); 82 + RoleState.EQUAL);
83 - case NONE: 83 + case NONE:
84 - controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()), 84 + controller.setRole(new Dpid(device.id().uri().getSchemeSpecificPart()),
85 - RoleState.SLAVE); 85 + RoleState.SLAVE);
86 - break; 86 + break;
87 - default: 87 + default:
88 - log.error("Unknown Mastership state : {}", newRole); 88 + log.error("Unknown Mastership state : {}", newRole);
89 89
90 } 90 }
91 log.info("Accepting mastership role change for device {}", device.id()); 91 log.info("Accepting mastership role change for device {}", device.id());
...@@ -102,11 +102,11 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -102,11 +102,11 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
102 102
103 DeviceDescription description = 103 DeviceDescription description =
104 new DefaultDeviceDescription(buildURI(dpid), Device.Type.SWITCH, 104 new DefaultDeviceDescription(buildURI(dpid), Device.Type.SWITCH,
105 - sw.manfacturerDescription(), 105 + sw.manfacturerDescription(),
106 - sw.hardwareDescription(), 106 + sw.hardwareDescription(),
107 - sw.softwareDescription(), 107 + sw.softwareDescription(),
108 - sw.softwareDescription()); 108 + sw.softwareDescription());
109 - providerService.deviceConnected(new DeviceId(uri), description); 109 + providerService.deviceConnected(deviceId(uri), description);
110 } 110 }
111 111
112 @Override 112 @Override
...@@ -115,7 +115,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr ...@@ -115,7 +115,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
115 return; 115 return;
116 } 116 }
117 URI uri = buildURI(dpid); 117 URI uri = buildURI(dpid);
118 - providerService.deviceDisconnected(new DeviceId(uri)); 118 + providerService.deviceDisconnected(deviceId(uri));
119 } 119 }
120 120
121 private URI buildURI(Dpid dpid) { 121 private URI buildURI(Dpid dpid) {
......