blob: 1fdf89ff07077a3e225cb4ea7890d7a6cb7bc080 [file] [log] [blame]
tome5ec3fd2014-09-04 15:18:06 -07001package org.onlab.onos.net.trivial.impl;
2
3import org.onlab.onos.net.DefaultDevice;
4import org.onlab.onos.net.Device;
5import org.onlab.onos.net.DeviceId;
6import org.onlab.onos.net.MastershipRole;
7import org.onlab.onos.net.Port;
8import org.onlab.onos.net.PortNumber;
9import org.onlab.onos.net.device.DeviceDescription;
10import org.onlab.onos.net.device.DeviceEvent;
11import org.onlab.onos.net.device.PortDescription;
12import org.onlab.onos.net.provider.ProviderId;
13
14import java.util.ArrayList;
15import java.util.Collections;
16import java.util.HashMap;
17import java.util.HashSet;
18import java.util.List;
19import java.util.Map;
20import java.util.Objects;
21import java.util.Set;
22import java.util.concurrent.ConcurrentHashMap;
23
24import static com.google.common.base.Preconditions.checkArgument;
25import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
26import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_MASTERSHIP_CHANGED;
27import static org.onlab.onos.net.device.DeviceEvent.Type.DEVICE_REMOVED;
28
29/**
30 * Manages inventory of infrastructure devices.
31 */
32class SimpleDeviceStore {
33
34 private final Map<DeviceId, DefaultDevice> devices = new ConcurrentHashMap<>();
35 private final Set<DeviceId> available = new HashSet<>();
36 private final Map<DeviceId, MastershipRole> roles = new HashMap<>();
37
38 /**
39 * Returns an iterable collection of all devices known to the system.
40 *
41 * @return device collection
42 */
43 Iterable<Device> getDevices() {
44 return Collections.unmodifiableSet(new HashSet<Device>(devices.values()));
45 }
46
47 /**
48 * Returns the device with the specified identifier.
49 *
50 * @param deviceId device identifier
51 * @return device
52 */
53 Device getDevice(DeviceId deviceId) {
54 return devices.get(deviceId);
55 }
56
57 /**
58 * Creates a new infrastructure device, or updates an existing one using
59 * the supplied device description.
60 *
61 * @param providerId provider identifier
62 * @param deviceId device identifier
63 * @param deviceDescription device description
64 * @return ready to send event describing what occurred; null if no change
65 */
66 DeviceEvent createOrUpdateDevice(ProviderId providerId, DeviceId deviceId,
67 DeviceDescription deviceDescription) {
68 DefaultDevice device = devices.get(deviceId);
69 if (device == null) {
70 return createDevice(providerId, deviceId, deviceDescription);
71 }
72 return updateDevice(providerId, device, deviceDescription);
73 }
74
75 // Creates the device and returns the appropriate event if necessary.
76 private DeviceEvent createDevice(ProviderId providerId, DeviceId deviceId,
77 DeviceDescription desc) {
78 DefaultDevice device = new DefaultDevice(providerId, deviceId, desc.type(),
79 desc.manufacturer(),
80 desc.hwVersion(), desc.swVersion(),
81 desc.serialNumber());
82 synchronized (this) {
83 devices.put(deviceId, device);
84 available.add(deviceId);
85 }
86 return new DeviceEvent(DeviceEvent.Type.DEVICE_ADDED, device);
87 }
88
89 // Updates the device and returns the appropriate event if necessary.
90 private DeviceEvent updateDevice(ProviderId providerId, DefaultDevice device,
91 DeviceDescription desc) {
92 // We allow only certain attributes to trigger update
93 if (!Objects.equals(device.hwVersion(), desc.hwVersion()) ||
94 !Objects.equals(device.swVersion(), desc.swVersion())) {
95 DefaultDevice updated = new DefaultDevice(providerId, device.id(),
96 desc.type(),
97 desc.manufacturer(),
98 desc.hwVersion(),
99 desc.swVersion(),
100 desc.serialNumber());
101 synchronized (this) {
102 devices.put(device.id(), updated);
103 available.add(device.id());
104 }
105 return new DeviceEvent(DeviceEvent.Type.DEVICE_UPDATED, device);
106 }
107
108 // Otherwise merely attempt to change availability
109 synchronized (this) {
110 boolean added = available.add(device.id());
111 return added ? new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device) : null;
112 }
113 }
114
115 /**
116 * Removes the specified infrastructure device.
117 *
118 * @param deviceId device identifier
119 * @return ready to send event describing what occurred; null if no change
120 */
121 DeviceEvent markOffline(DeviceId deviceId) {
122 synchronized (this) {
123 Device device = devices.get(deviceId);
124 checkArgument(device != null, "Device with ID %s is not found", deviceId);
125 boolean removed = available.remove(deviceId);
126 return removed ? new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device) : null;
127 }
128 }
129
130 /**
131 * Updates the ports of the specified infrastructure device using the given
132 * list of port descriptions. The list is assumed to be comprehensive.
133 *
134 * @param deviceId device identifier
135 * @param portDescriptions list of port descriptions
136 * @return ready to send events describing what occurred; empty list if no change
137 */
138 List<DeviceEvent> updatePorts(DeviceId deviceId,
139 List<PortDescription> portDescriptions) {
140 return new ArrayList<>();
141 }
142
143 /**
144 * Updates the port status of the specified infrastructure device using the
145 * given port description.
146 *
147 * @param deviceId device identifier
148 * @param portDescription port description
149 * @return ready to send event describing what occurred; null if no change
150 */
151 DeviceEvent updatePortStatus(DeviceId deviceId,
152 PortDescription portDescription) {
153 return null;
154 }
155
156 /**
157 * Returns the list of ports that belong to the specified device.
158 *
159 * @param deviceId device identifier
160 * @return list of device ports
161 */
162 List<Port> getPorts(DeviceId deviceId) {
163 return null;
164 }
165
166 /**
167 * Returns the specified device port.
168 *
169 * @param deviceId device identifier
170 * @param portNumber port number
171 * @return device port
172 */
173 Port getPort(DeviceId deviceId, PortNumber portNumber) {
174 return null;
175 }
176
177 /**
178 * Returns the mastership role determined for this device.
179 *
180 * @param deviceId device identifier
181 * @return mastership role
182 */
183 MastershipRole getRole(DeviceId deviceId) {
184 MastershipRole role = roles.get(deviceId);
185 return role != null ? role : MastershipRole.NONE;
186 }
187
188 /**
189 * Administratively sets the role of the specified device.
190 *
191 * @param deviceId device identifier
192 * @param role mastership role to apply
193 * @return mastership role change event or null if no change
194 */
195 DeviceEvent setRole(DeviceId deviceId, MastershipRole role) {
196 Device device = getDevice(deviceId);
197 checkArgument(device != null, "Device with ID %s not found");
198 MastershipRole oldRole = roles.put(deviceId, role);
199 return oldRole == role ? null : new DeviceEvent(DEVICE_MASTERSHIP_CHANGED, device);
200 }
201
202 /**
203 * Administratively removes the specified device from the store.
204 *
205 * @param deviceId device to be removed
206 */
207 DeviceEvent removeDevice(DeviceId deviceId) {
208 synchronized (this) {
209 roles.remove(deviceId);
210 Device device = devices.remove(deviceId);
211 return device != null ? new DeviceEvent(DEVICE_REMOVED, device) : null;
212 }
213 }
214}