alshabib

Merge branch 'master' of ssh://gerrit.onlab.us:29418/onos-next

1 +package org.onlab.onos.net;
2 +
3 +import java.util.Objects;
4 +
5 +import static com.google.common.base.Objects.toStringHelper;
6 +
7 +/**
8 + * Default port implementation.
9 + */
10 +public class DefaultPort implements Port {
11 +
12 + private final Element element;
13 + private final PortNumber number;
14 + private final boolean isEnabled;
15 +
16 + /**
17 + * Creates a network element attributed to the specified provider.
18 + *
19 + * @param element parent network element
20 + * @param number port number
21 + * @param isEnabled indicator whether the port is up and active
22 + */
23 + public DefaultPort(Element element, PortNumber number,
24 + boolean isEnabled) {
25 + this.element = element;
26 + this.number = number;
27 + this.isEnabled = isEnabled;
28 + }
29 +
30 + @Override
31 + public int hashCode() {
32 + return Objects.hash(number, isEnabled);
33 + }
34 +
35 + @Override
36 + public boolean equals(Object obj) {
37 + if (obj instanceof DefaultPort) {
38 + final DefaultPort other = (DefaultPort) obj;
39 + return Objects.equals(this.element.id(), other.element.id()) &&
40 + Objects.equals(this.number, other.number) &&
41 + Objects.equals(this.isEnabled, other.isEnabled);
42 + }
43 + return false;
44 + }
45 +
46 + @Override
47 + public String toString() {
48 + return toStringHelper(this)
49 + .add("element", element.id())
50 + .add("number", number)
51 + .add("isEnabled", isEnabled)
52 + .toString();
53 + }
54 +
55 + @Override
56 + public PortNumber number() {
57 + return number;
58 + }
59 +
60 + @Override
61 + public boolean isEnabled() {
62 + return isEnabled;
63 + }
64 +
65 + @Override
66 + public Element element() {
67 + return element;
68 + }
69 +
70 +}
...@@ -20,11 +20,11 @@ public interface Port { ...@@ -20,11 +20,11 @@ public interface Port {
20 boolean isEnabled(); 20 boolean isEnabled();
21 21
22 /** 22 /**
23 - * Returns the identifier of the network element to which this port belongs. 23 + * Returns the parent network element to which this port belongs.
24 * 24 *
25 * @return parent network element 25 * @return parent network element
26 */ 26 */
27 - Element parent(); 27 + Element element();
28 28
29 // set of port attributes 29 // set of port attributes
30 30
......
...@@ -2,12 +2,15 @@ package org.onlab.onos.net.device; ...@@ -2,12 +2,15 @@ package org.onlab.onos.net.device;
2 2
3 import org.onlab.onos.event.AbstractEvent; 3 import org.onlab.onos.event.AbstractEvent;
4 import org.onlab.onos.net.Device; 4 import org.onlab.onos.net.Device;
5 +import org.onlab.onos.net.Port;
5 6
6 /** 7 /**
7 * Describes infrastructure device event. 8 * Describes infrastructure device event.
8 */ 9 */
9 public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { 10 public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> {
10 11
12 + private final Port port;
13 +
11 /** 14 /**
12 * Type of device events. 15 * Type of device events.
13 */ 16 */
...@@ -42,7 +45,22 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { ...@@ -42,7 +45,22 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> {
42 * Signifies that the current controller instance relationship has 45 * Signifies that the current controller instance relationship has
43 * changed with respect to a device. 46 * changed with respect to a device.
44 */ 47 */
45 - DEVICE_MASTERSHIP_CHANGED 48 + DEVICE_MASTERSHIP_CHANGED,
49 +
50 + /**
51 + * Signifies that a port has been added.
52 + */
53 + PORT_ADDED,
54 +
55 + /**
56 + * Signifies that a port has been updated.
57 + */
58 + PORT_UPDATED,
59 +
60 + /**
61 + * Signifies that a port has been removed.
62 + */
63 + PORT_REMOVED
46 } 64 }
47 65
48 /** 66 /**
...@@ -53,7 +71,20 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { ...@@ -53,7 +71,20 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> {
53 * @param device event device subject 71 * @param device event device subject
54 */ 72 */
55 public DeviceEvent(Type type, Device device) { 73 public DeviceEvent(Type type, Device device) {
74 + this(type, device, null);
75 + }
76 +
77 + /**
78 + * Creates an event of a given type and for the specified device, port
79 + * and the current time.
80 + *
81 + * @param type device event type
82 + * @param device event device subject
83 + * @param port optional port subject
84 + */
85 + public DeviceEvent(Type type, Device device, Port port) {
56 super(type, device); 86 super(type, device);
87 + this.port = port;
57 } 88 }
58 89
59 /** 90 /**
...@@ -61,10 +92,21 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> { ...@@ -61,10 +92,21 @@ public class DeviceEvent extends AbstractEvent<DeviceEvent.Type, Device> {
61 * 92 *
62 * @param type device event type 93 * @param type device event type
63 * @param device event device subject 94 * @param device event device subject
95 + * @param port optional port subject
64 * @param time occurrence time 96 * @param time occurrence time
65 */ 97 */
66 - public DeviceEvent(Type type, Device device, long time) { 98 + public DeviceEvent(Type type, Device device, Port port, long time) {
67 super(type, device, time); 99 super(type, device, time);
100 + this.port = port;
101 + }
102 +
103 + /**
104 + * Returns the port subject.
105 + *
106 + * @return port subject or null if the event is not port specific.
107 + */
108 + Port port() {
109 + return port;
68 } 110 }
69 111
70 } 112 }
......
...@@ -3,9 +3,13 @@ package org.onlab.onos.net.device; ...@@ -3,9 +3,13 @@ package org.onlab.onos.net.device;
3 import org.junit.Test; 3 import org.junit.Test;
4 import org.onlab.onos.event.AbstractEventTest; 4 import org.onlab.onos.event.AbstractEventTest;
5 import org.onlab.onos.net.DefaultDevice; 5 import org.onlab.onos.net.DefaultDevice;
6 +import org.onlab.onos.net.DefaultPort;
6 import org.onlab.onos.net.Device; 7 import org.onlab.onos.net.Device;
8 +import org.onlab.onos.net.Port;
9 +import org.onlab.onos.net.PortNumber;
7 import org.onlab.onos.net.provider.ProviderId; 10 import org.onlab.onos.net.provider.ProviderId;
8 11
12 +import static org.junit.Assert.assertEquals;
9 import static org.onlab.onos.net.DeviceId.deviceId; 13 import static org.onlab.onos.net.DeviceId.deviceId;
10 14
11 /** 15 /**
...@@ -21,17 +25,19 @@ public class DeviceEventTest extends AbstractEventTest { ...@@ -21,17 +25,19 @@ public class DeviceEventTest extends AbstractEventTest {
21 @Test 25 @Test
22 public void withTime() { 26 public void withTime() {
23 Device device = createDevice(); 27 Device device = createDevice();
28 + Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
24 DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, 29 DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED,
25 - device, 123L); 30 + device, port, 123L);
26 validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L); 31 validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, 123L);
32 + assertEquals("incorrect port", port, event.port());
27 } 33 }
28 34
29 @Test 35 @Test
30 public void withoutTime() { 36 public void withoutTime() {
31 Device device = createDevice(); 37 Device device = createDevice();
38 + Port port = new DefaultPort(device, PortNumber.portNumber(123L), true);
32 long before = System.currentTimeMillis(); 39 long before = System.currentTimeMillis();
33 - DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, 40 + DeviceEvent event = new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
34 - device);
35 long after = System.currentTimeMillis(); 41 long after = System.currentTimeMillis();
36 validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, before, after); 42 validateEvent(event, DeviceEvent.Type.DEVICE_ADDED, device, before, after);
37 } 43 }
......
1 package org.onlab.onos.net.trivial.impl; 1 package org.onlab.onos.net.trivial.impl;
2 2
3 +import com.google.common.collect.ImmutableList;
3 import org.onlab.onos.net.DefaultDevice; 4 import org.onlab.onos.net.DefaultDevice;
5 +import org.onlab.onos.net.DefaultPort;
4 import org.onlab.onos.net.Device; 6 import org.onlab.onos.net.Device;
5 import org.onlab.onos.net.DeviceId; 7 import org.onlab.onos.net.DeviceId;
6 import org.onlab.onos.net.MastershipRole; 8 import org.onlab.onos.net.MastershipRole;
...@@ -13,7 +15,9 @@ import org.onlab.onos.net.provider.ProviderId; ...@@ -13,7 +15,9 @@ import org.onlab.onos.net.provider.ProviderId;
13 15
14 import java.util.ArrayList; 16 import java.util.ArrayList;
15 import java.util.Collections; 17 import java.util.Collections;
18 +import java.util.HashMap;
16 import java.util.HashSet; 19 import java.util.HashSet;
20 +import java.util.Iterator;
17 import java.util.List; 21 import java.util.List;
18 import java.util.Map; 22 import java.util.Map;
19 import java.util.Objects; 23 import java.util.Objects;
...@@ -21,18 +25,19 @@ import java.util.Set; ...@@ -21,18 +25,19 @@ import java.util.Set;
21 import java.util.concurrent.ConcurrentHashMap; 25 import java.util.concurrent.ConcurrentHashMap;
22 26
23 import static com.google.common.base.Preconditions.checkArgument; 27 import static com.google.common.base.Preconditions.checkArgument;
24 -import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED; 28 +import static org.onlab.onos.net.device.DeviceEvent.Type.*;
25 -import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED;
26 -import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_REMOVED;
27 29
28 /** 30 /**
29 * Manages inventory of infrastructure devices. 31 * Manages inventory of infrastructure devices.
30 */ 32 */
31 class SimpleDeviceStore { 33 class SimpleDeviceStore {
32 34
35 + public static final String DEVICE_NOT_FOUND = "Device with ID %s not found";
36 +
33 private final Map<DeviceId, DefaultDevice> devices = new ConcurrentHashMap<>(); 37 private final Map<DeviceId, DefaultDevice> devices = new ConcurrentHashMap<>();
34 private final Map<DeviceId, MastershipRole> roles = new ConcurrentHashMap<>(); 38 private final Map<DeviceId, MastershipRole> roles = new ConcurrentHashMap<>();
35 private final Set<DeviceId> availableDevices = new HashSet<>(); 39 private final Set<DeviceId> availableDevices = new HashSet<>();
40 + private final Map<DeviceId, Map<PortNumber, Port>> devicePorts = new HashMap<>();
36 41
37 /** 42 /**
38 * Returns an iterable collection of all devices known to the system. 43 * Returns an iterable collection of all devices known to the system.
...@@ -82,7 +87,7 @@ class SimpleDeviceStore { ...@@ -82,7 +87,7 @@ class SimpleDeviceStore {
82 devices.put(deviceId, device); 87 devices.put(deviceId, device);
83 availableDevices.add(deviceId); 88 availableDevices.add(deviceId);
84 } 89 }
85 - return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device); 90 + return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device, null);
86 } 91 }
87 92
88 // Updates the device and returns the appropriate event if necessary. 93 // Updates the device and returns the appropriate event if necessary.
...@@ -101,13 +106,14 @@ class SimpleDeviceStore { ...@@ -101,13 +106,14 @@ class SimpleDeviceStore {
101 devices.put(device.id(), updated); 106 devices.put(device.id(), updated);
102 availableDevices.add(device.id()); 107 availableDevices.add(device.id());
103 } 108 }
104 - return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, device); 109 + return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, device, null);
105 } 110 }
106 111
107 // Otherwise merely attempt to change availability 112 // Otherwise merely attempt to change availability
108 synchronized (this) { 113 synchronized (this) {
109 boolean added = availableDevices.add(device.id()); 114 boolean added = availableDevices.add(device.id());
110 - return added ? new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device) : null; 115 + return !added ? null :
116 + new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
111 } 117 }
112 } 118 }
113 119
...@@ -120,9 +126,10 @@ class SimpleDeviceStore { ...@@ -120,9 +126,10 @@ class SimpleDeviceStore {
120 DeviceEvent markOffline(DeviceId deviceId) { 126 DeviceEvent markOffline(DeviceId deviceId) {
121 synchronized (this) { 127 synchronized (this) {
122 Device device = devices.get(deviceId); 128 Device device = devices.get(deviceId);
123 - checkArgument(device != null, "Device with ID %s is not found", deviceId); 129 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
124 boolean removed = availableDevices.remove(deviceId); 130 boolean removed = availableDevices.remove(deviceId);
125 - return removed ? new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device) : null; 131 + return !removed ? null :
132 + new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device, null);
126 } 133 }
127 } 134 }
128 135
...@@ -136,7 +143,79 @@ class SimpleDeviceStore { ...@@ -136,7 +143,79 @@ class SimpleDeviceStore {
136 */ 143 */
137 List<DeviceEvent> updatePorts(DeviceId deviceId, 144 List<DeviceEvent> updatePorts(DeviceId deviceId,
138 List<PortDescription> portDescriptions) { 145 List<PortDescription> portDescriptions) {
139 - return new ArrayList<>(); 146 + List<DeviceEvent> events = new ArrayList<>();
147 + synchronized (this) {
148 + Device device = devices.get(deviceId);
149 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
150 + Map<PortNumber, Port> ports = getPortMap(deviceId);
151 +
152 + // Add new ports
153 + Set<PortNumber> processed = new HashSet<>();
154 + for (PortDescription portDescription : portDescriptions) {
155 + Port port = ports.get(portDescription.portNumber());
156 + DeviceEvent event = port == null ?
157 + createPort(device, portDescription, ports) :
158 + updatePort(device, port, portDescription, ports);
159 + processed.add(portDescription.portNumber());
160 + }
161 +
162 + events.addAll(pruneOldPorts(device, ports, processed));
163 + }
164 + return events;
165 + }
166 +
167 + // Creates a new port based on the port description adds it to the map and
168 + // Returns corresponding event.
169 + private DeviceEvent createPort(Device device, PortDescription portDescription,
170 + Map<PortNumber, Port> ports) {
171 + DefaultPort port = new DefaultPort(device, portDescription.portNumber(),
172 + portDescription.isEnabled());
173 + ports.put(port.number(), port);
174 + return new DeviceEvent(PORT_ADDED, device, port);
175 + }
176 +
177 + // CHecks if the specified port requires update and if so, it replaces the
178 + // existing entry in the map and returns corresponding event.
179 + private DeviceEvent updatePort(Device device, Port port,
180 + PortDescription portDescription,
181 + Map<PortNumber, Port> ports) {
182 + if (port.isEnabled() != portDescription.isEnabled()) {
183 + DefaultPort updatedPort =
184 + new DefaultPort(device, portDescription.portNumber(),
185 + portDescription.isEnabled());
186 + ports.put(port.number(), updatedPort);
187 + return new DeviceEvent(PORT_UPDATED, device, port);
188 + }
189 + return null;
190 + }
191 +
192 + // Prunes the specified list of ports based on which ports are in the
193 + // processed list and returns list of corresponding events.
194 + private List<DeviceEvent> pruneOldPorts(Device device,
195 + Map<PortNumber, Port> ports,
196 + Set<PortNumber> processed) {
197 + List<DeviceEvent> events = new ArrayList<>();
198 + Iterator<PortNumber> iterator = ports.keySet().iterator();
199 + while (iterator.hasNext()) {
200 + PortNumber portNumber = iterator.next();
201 + if (processed.contains(portNumber)) {
202 + events.add(new DeviceEvent(PORT_REMOVED, device,
203 + ports.get(portNumber)));
204 + iterator.remove();
205 + }
206 + }
207 + return events;
208 + }
209 +
210 + // Gets the map of ports for the specified device; if one does not already
211 + // exist, it creates and registers a new one.
212 + private Map<PortNumber, Port> getPortMap(DeviceId deviceId) {
213 + Map<PortNumber, Port> ports = devicePorts.get(deviceId);
214 + if (ports == null) {
215 + ports = new HashMap<>();
216 + devicePorts.put(deviceId, ports);
217 + }
218 + return ports;
140 } 219 }
141 220
142 /** 221 /**
...@@ -149,7 +228,13 @@ class SimpleDeviceStore { ...@@ -149,7 +228,13 @@ class SimpleDeviceStore {
149 */ 228 */
150 DeviceEvent updatePortStatus(DeviceId deviceId, 229 DeviceEvent updatePortStatus(DeviceId deviceId,
151 PortDescription portDescription) { 230 PortDescription portDescription) {
152 - return null; 231 + synchronized (this) {
232 + Device device = devices.get(deviceId);
233 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
234 + Map<PortNumber, Port> ports = getPortMap(deviceId);
235 + Port port = ports.get(portDescription.portNumber());
236 + return updatePort(device, port, portDescription, ports);
237 + }
153 } 238 }
154 239
155 /** 240 /**
...@@ -159,7 +244,8 @@ class SimpleDeviceStore { ...@@ -159,7 +244,8 @@ class SimpleDeviceStore {
159 * @return list of device ports 244 * @return list of device ports
160 */ 245 */
161 List<Port> getPorts(DeviceId deviceId) { 246 List<Port> getPorts(DeviceId deviceId) {
162 - return null; 247 + Map<PortNumber, Port> ports = devicePorts.get(deviceId);
248 + return ports == null ? new ArrayList<Port>() : ImmutableList.copyOf(ports.values());
163 } 249 }
164 250
165 /** 251 /**
...@@ -170,7 +256,8 @@ class SimpleDeviceStore { ...@@ -170,7 +256,8 @@ class SimpleDeviceStore {
170 * @return device port 256 * @return device port
171 */ 257 */
172 Port getPort(DeviceId deviceId, PortNumber portNumber) { 258 Port getPort(DeviceId deviceId, PortNumber portNumber) {
173 - return null; 259 + Map<PortNumber, Port> ports = devicePorts.get(deviceId);
260 + return ports == null ? null : ports.get(portNumber);
174 } 261 }
175 262
176 /** 263 /**
...@@ -194,9 +281,10 @@ class SimpleDeviceStore { ...@@ -194,9 +281,10 @@ class SimpleDeviceStore {
194 DeviceEvent setRole(DeviceId deviceId, MastershipRole role) { 281 DeviceEvent setRole(DeviceId deviceId, MastershipRole role) {
195 synchronized (this) { 282 synchronized (this) {
196 Device device = getDevice(deviceId); 283 Device device = getDevice(deviceId);
197 - checkArgument(device != null, "Device with ID %s not found"); 284 + checkArgument(device != null, DEVICE_NOT_FOUND, deviceId);
198 MastershipRole oldRole = roles.put(deviceId, role); 285 MastershipRole oldRole = roles.put(deviceId, role);
199 - return oldRole == role ? null : new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device); 286 + return oldRole == role ? null :
287 + new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device, null);
200 } 288 }
201 } 289 }
202 290
...@@ -209,7 +297,9 @@ class SimpleDeviceStore { ...@@ -209,7 +297,9 @@ class SimpleDeviceStore {
209 synchronized (this) { 297 synchronized (this) {
210 roles.remove(deviceId); 298 roles.remove(deviceId);
211 Device device = devices.remove(deviceId); 299 Device device = devices.remove(deviceId);
212 - return device != null ? new DeviceEvent(DEVICE_REMOVED, device) : null; 300 + return device == null ? null :
301 + new DeviceEvent(DEVICE_REMOVED, device, null);
213 } 302 }
214 } 303 }
304 +
215 } 305 }
......
...@@ -24,6 +24,8 @@ import org.projectfloodlight.openflow.types.*; ...@@ -24,6 +24,8 @@ import org.projectfloodlight.openflow.types.*;
24 import org.projectfloodlight.openflow.util.*; 24 import org.projectfloodlight.openflow.util.*;
25 import org.projectfloodlight.openflow.exceptions.*; 25 import org.projectfloodlight.openflow.exceptions.*;
26 import org.jboss.netty.buffer.ChannelBuffer; 26 import org.jboss.netty.buffer.ChannelBuffer;
27 +
28 +import java.nio.ByteBuffer;
27 import java.util.Set; 29 import java.util.Set;
28 30
29 abstract class OFActionBsnVer13 { 31 abstract class OFActionBsnVer13 {
...@@ -36,7 +38,7 @@ abstract class OFActionBsnVer13 { ...@@ -36,7 +38,7 @@ abstract class OFActionBsnVer13 {
36 38
37 static class Reader implements OFMessageReader<OFActionBsn> { 39 static class Reader implements OFMessageReader<OFActionBsn> {
38 @Override 40 @Override
39 - public OFActionBsn readFrom(ChannelBuffer bb) throws OFParseError { 41 + public OFActionBsn readFrom(ByteBuffer bb) throws OFParseError {
40 if(bb.readableBytes() < MINIMUM_LENGTH) 42 if(bb.readableBytes() < MINIMUM_LENGTH)
41 return null; 43 return null;
42 int start = bb.readerIndex(); 44 int start = bb.readerIndex();
......