blob: 28a9821542366c6dbf1d5ba3d2cdc4537470c617 [file] [log] [blame]
Jonathan Hart472062d2014-04-03 10:56:48 -07001package net.onrc.onos.core.topology;
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -08002
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -07003import java.nio.ByteBuffer;
4import java.nio.charset.StandardCharsets;
weibitcef09862014-07-11 17:05:16 -07005import java.util.Objects;
6
Pavlin Radoslavovd7b792e2014-08-01 02:47:47 -07007import net.onrc.onos.core.util.Dpid;
Pavlin Radoslavova5637c02014-07-30 15:55:11 -07008import net.onrc.onos.core.util.OnosInstanceId;
9
10import static com.google.common.base.Preconditions.checkNotNull;
weibitcef09862014-07-11 17:05:16 -070011
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080012/**
13 * Self-contained Topology event Object
Ray Milkey269ffb92014-04-03 14:43:30 -070014 * <p/>
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080015 * TODO: For now the topology event contains one of the following events:
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -070016 * Switch Mastership, Switch, Port, Link, Host. In the future it will contain
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070017 * multiple events in a single transaction.
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070018 * TODO: This class should become immutable after its internals and usage
19 * are finalized.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080020 */
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070021public final class TopologyEvent {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -070022 private final MastershipEvent mastershipEvent; // Set for Mastership event
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070023 private final SwitchEvent switchEvent; // Set for Switch event
24 private final PortEvent portEvent; // Set for Port event
25 private final LinkEvent linkEvent; // Set for Link event
26 private final HostEvent hostEvent; // Set for Host event
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070027 private final OnosInstanceId onosInstanceId; // The ONOS Instance ID
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080028
29 /**
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070030 * Default constructor for serializer.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080031 */
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070032 @Deprecated
33 protected TopologyEvent() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -070034 mastershipEvent = null;
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070035 switchEvent = null;
36 portEvent = null;
37 linkEvent = null;
38 hostEvent = null;
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070039 onosInstanceId = null;
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -080040 }
41
42 /**
Pavlin Radoslavov054cd592014-08-07 20:57:16 -070043 * Constructor for creating an empty (NO-OP) Topology Event.
44 *
45 * @param onosInstanceId the ONOS Instance ID that originates the event.
46 */
47 protected TopologyEvent(OnosInstanceId onosInstanceId) {
48 mastershipEvent = null;
49 switchEvent = null;
50 portEvent = null;
51 linkEvent = null;
52 hostEvent = null;
53 this.onosInstanceId = checkNotNull(onosInstanceId);
54 }
55
56 /**
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070057 * Constructor for given Switch Mastership event.
58 *
59 * @param mastershipEvent the Switch Mastership event to use.
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070060 * @param onosInstanceId the ONOS Instance ID that originates the event.
Pavlin Radoslavov695f8952014-07-23 16:57:01 -070061 */
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070062 TopologyEvent(MastershipEvent mastershipEvent,
63 OnosInstanceId onosInstanceId) {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -070064 this.mastershipEvent = checkNotNull(mastershipEvent);
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070065 this.switchEvent = null;
66 this.portEvent = null;
67 this.linkEvent = null;
68 this.hostEvent = null;
Pavlin Radoslavova5637c02014-07-30 15:55:11 -070069 this.onosInstanceId = checkNotNull(onosInstanceId);
70 }
71
72 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -070073 * Constructor for given Switch event.
74 *
75 * @param switchEvent the Switch event to use.
76 * @param onosInstanceId the ONOS Instance ID that originates the event.
77 */
78 TopologyEvent(SwitchEvent switchEvent, OnosInstanceId onosInstanceId) {
79 this.mastershipEvent = null;
80 this.switchEvent = checkNotNull(switchEvent);
81 this.portEvent = null;
82 this.linkEvent = null;
83 this.hostEvent = null;
84 this.onosInstanceId = checkNotNull(onosInstanceId);
85 }
86
87 /**
88 * Constructor for given Port event.
89 *
90 * @param portEvent the Port event to use.
91 * @param onosInstanceId the ONOS Instance ID that originates the event.
92 */
93 TopologyEvent(PortEvent portEvent, OnosInstanceId onosInstanceId) {
94 this.mastershipEvent = null;
95 this.switchEvent = null;
96 this.portEvent = checkNotNull(portEvent);
97 this.linkEvent = null;
98 this.hostEvent = null;
99 this.onosInstanceId = checkNotNull(onosInstanceId);
100 }
101
102 /**
103 * Constructor for given Link event.
104 *
105 * @param linkEvent the Link event to use.
106 * @param onosInstanceId the ONOS Instance ID that originates the event.
107 */
108 TopologyEvent(LinkEvent linkEvent, OnosInstanceId onosInstanceId) {
109 this.mastershipEvent = null;
110 this.switchEvent = null;
111 this.portEvent = null;
112 this.linkEvent = checkNotNull(linkEvent);
113 this.hostEvent = null;
114 this.onosInstanceId = checkNotNull(onosInstanceId);
115 }
116
117 /**
118 * Constructor for given Host event.
119 *
120 * @param hostEvent the Host event to use.
121 * @param onosInstanceId the ONOS Instance ID that originates the event.
122 */
123 TopologyEvent(HostEvent hostEvent, OnosInstanceId onosInstanceId) {
124 this.mastershipEvent = null;
125 this.switchEvent = null;
126 this.portEvent = null;
127 this.linkEvent = null;
128 this.hostEvent = checkNotNull(hostEvent);
129 this.onosInstanceId = checkNotNull(onosInstanceId);
130 }
131
132 /**
133 * Gets the Mastership event.
134 *
135 * @return the Mastership event.
136 */
137 public MastershipEvent getMastershipEvent() {
138 return mastershipEvent;
139 }
140
141 /**
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700142 * Gets the Switch event.
143 *
144 * @return the Switch event.
145 */
146 public SwitchEvent getSwitchEvent() {
147 return switchEvent;
148 }
149
150 /**
151 * Gets the Port event.
152 *
153 * @return the Port event.
154 */
155 public PortEvent getPortEvent() {
156 return portEvent;
157 }
158
159 /**
160 * Gets the Link event.
161 *
162 * @return the Link event.
163 */
164 public LinkEvent getLinkEvent() {
165 return linkEvent;
166 }
167
168 /**
169 * Gets the Host event.
170 *
171 * @return the Host event.
172 */
173 public HostEvent getHostEvent() {
174 return hostEvent;
175 }
176
177 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700178 * Gets the ONOS Instance ID.
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700179 *
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700180 * @return the ONOS Instance ID.
Pavlin Radoslavova5637c02014-07-30 15:55:11 -0700181 */
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700182 public OnosInstanceId getOnosInstanceId() {
183 return onosInstanceId;
Pavlin Radoslavov695f8952014-07-23 16:57:01 -0700184 }
185
186 /**
Pavlin Radoslavovd7b792e2014-08-01 02:47:47 -0700187 * Gets the event origin DPID.
188 *
189 * @return the event origin DPID.
190 */
191 public Dpid getOriginDpid() {
192 if (mastershipEvent != null) {
193 return mastershipEvent.getOriginDpid();
194 }
195 if (switchEvent != null) {
196 return switchEvent.getOriginDpid();
197 }
198 if (portEvent != null) {
199 return portEvent.getOriginDpid();
200 }
201 if (linkEvent != null) {
202 return linkEvent.getOriginDpid();
203 }
204 if (hostEvent != null) {
205 return hostEvent.getOriginDpid();
206 }
207 return null;
208 }
209
210 /**
211 * Tests whether the event origin DPID equals the specified DPID.
212 *
213 * @param dpid the DPID to compare against.
214 * @return true if the event origin Dpid equals the specified DPID.
215 */
216 public boolean equalsOriginDpid(Dpid dpid) {
217 return dpid.equals(getOriginDpid());
218 }
219
220 /**
Pavlin Radoslavovae7e8482014-08-11 16:58:19 -0700221 * Returns the config state of the topology element.
222 *
223 * @return the config state of the topology element.
224 */
225 public ConfigState getConfigState() {
226 if (mastershipEvent != null) {
227 return mastershipEvent.getConfigState();
228 }
229 if (switchEvent != null) {
230 return switchEvent.getConfigState();
231 }
232 if (portEvent != null) {
233 return portEvent.getConfigState();
234 }
235 if (linkEvent != null) {
236 return linkEvent.getConfigState();
237 }
238 if (hostEvent != null) {
239 return hostEvent.getConfigState();
240 }
241 return ConfigState.NOT_CONFIGURED; // Default: not configured
242 }
243
244 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700245 * Checks if all events contained are equal.
Yuta HIGUCHIccab05d2014-07-26 22:42:28 -0700246 *
247 * @param obj TopologyEvent to compare against
weibitcef09862014-07-11 17:05:16 -0700248 */
249 @Override
250 public boolean equals(Object obj) {
251 if (this == obj) {
252 return true;
253 }
254
255 if (obj == null) {
256 return false;
257 }
258
259 if (getClass() != obj.getClass()) {
260 return false;
261 }
262
263 TopologyEvent other = (TopologyEvent) obj;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700264 return Objects.equals(mastershipEvent, other.mastershipEvent) &&
265 Objects.equals(switchEvent, other.switchEvent) &&
266 Objects.equals(portEvent, other.portEvent) &&
267 Objects.equals(linkEvent, other.linkEvent) &&
268 Objects.equals(hostEvent, other.hostEvent) &&
269 Objects.equals(onosInstanceId, other.onosInstanceId);
weibitcef09862014-07-11 17:05:16 -0700270 }
271
272 @Override
273 public int hashCode() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700274 return Objects.hash(mastershipEvent, switchEvent, portEvent,
275 linkEvent, hostEvent, onosInstanceId);
weibitcef09862014-07-11 17:05:16 -0700276 }
277
278 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700279 * Gets the string representation of the event.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800280 *
281 * @return the string representation of the event.
282 */
283 @Override
284 public String toString() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700285 String eventStr = null;
286
287 //
288 // Get the Event string
289 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700290 stringLabel: {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700291 if (mastershipEvent != null) {
292 eventStr = mastershipEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700293 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700294 }
295 if (switchEvent != null) {
296 eventStr = switchEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700297 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700298 }
299 if (portEvent != null) {
300 eventStr = portEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700301 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700302 }
303 if (linkEvent != null) {
304 eventStr = linkEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700305 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700306 }
307 if (hostEvent != null) {
308 eventStr = hostEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700309 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700310 }
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700311 // Test whether this is NO-OP event
312 if (onosInstanceId != null) {
313 eventStr = "NO-OP";
314 break stringLabel;
315 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700316 // No event found
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700317 return "[Unknown TopologyEvent]";
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700318 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700319
320 return "[TopologyEvent " + eventStr + " from " +
321 onosInstanceId.toString() + "]";
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800322 }
323
324 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700325 * Gets the Topology event ID as a byte array.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800326 *
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700327 * @return the Topology event ID as a byte array.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800328 */
329 public byte[] getID() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700330 return getIDasByteBuffer().array();
331 }
332
333 /**
334 * Gets the Topology event ID as a ByteBuffer.
335 *
336 * @return the Topology event ID as a ByteBuffer.
337 */
338 public ByteBuffer getIDasByteBuffer() {
339 ByteBuffer eventId = null;
340
341 //
342 // Get the Event ID
343 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700344 idLabel: {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700345 if (mastershipEvent != null) {
346 eventId = mastershipEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700347 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700348 }
349 if (switchEvent != null) {
350 eventId = switchEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700351 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700352 }
353 if (portEvent != null) {
354 eventId = portEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700355 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700356 }
357 if (linkEvent != null) {
358 eventId = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700359 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700360 }
361 if (hostEvent != null) {
362 eventId = hostEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700363 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700364 }
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700365 // Test whether this is NO-OP event
366 if (onosInstanceId != null) {
367 String id = "NO-OP";
368 eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
369 break idLabel;
370 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700371 // No event found
372 throw new IllegalStateException("Invalid TopologyEvent ID");
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700373 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700374
375 //
376 // Prepare the ONOS Instance ID. The '@' separator is needed to avoid
377 // potential key collisions.
378 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700379 byte[] onosId =
380 ("@" + onosInstanceId.toString()).getBytes(StandardCharsets.UTF_8);
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700381
382 // Concatenate the IDs
383 ByteBuffer buf =
384 ByteBuffer.allocate(eventId.capacity() + onosId.length);
385 buf.put(eventId);
386 buf.put(onosId);
387 buf.flip();
388 return buf;
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800389 }
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800390}