blob: 82fa6e54f340be67b93af928b86049af7eff6b4a [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 Radoslavovcac157d2014-07-31 13:54:08 -0700221 * Checks if all events contained are equal.
Yuta HIGUCHIccab05d2014-07-26 22:42:28 -0700222 *
223 * @param obj TopologyEvent to compare against
weibitcef09862014-07-11 17:05:16 -0700224 */
225 @Override
226 public boolean equals(Object obj) {
227 if (this == obj) {
228 return true;
229 }
230
231 if (obj == null) {
232 return false;
233 }
234
235 if (getClass() != obj.getClass()) {
236 return false;
237 }
238
239 TopologyEvent other = (TopologyEvent) obj;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700240 return Objects.equals(mastershipEvent, other.mastershipEvent) &&
241 Objects.equals(switchEvent, other.switchEvent) &&
242 Objects.equals(portEvent, other.portEvent) &&
243 Objects.equals(linkEvent, other.linkEvent) &&
244 Objects.equals(hostEvent, other.hostEvent) &&
245 Objects.equals(onosInstanceId, other.onosInstanceId);
weibitcef09862014-07-11 17:05:16 -0700246 }
247
248 @Override
249 public int hashCode() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700250 return Objects.hash(mastershipEvent, switchEvent, portEvent,
251 linkEvent, hostEvent, onosInstanceId);
weibitcef09862014-07-11 17:05:16 -0700252 }
253
254 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700255 * Gets the string representation of the event.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800256 *
257 * @return the string representation of the event.
258 */
259 @Override
260 public String toString() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700261 String eventStr = null;
262
263 //
264 // Get the Event string
265 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700266 stringLabel: {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700267 if (mastershipEvent != null) {
268 eventStr = mastershipEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700269 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700270 }
271 if (switchEvent != null) {
272 eventStr = switchEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700273 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700274 }
275 if (portEvent != null) {
276 eventStr = portEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700277 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700278 }
279 if (linkEvent != null) {
280 eventStr = linkEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700281 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700282 }
283 if (hostEvent != null) {
284 eventStr = hostEvent.toString();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700285 break stringLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700286 }
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700287 // Test whether this is NO-OP event
288 if (onosInstanceId != null) {
289 eventStr = "NO-OP";
290 break stringLabel;
291 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700292 // No event found
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700293 return "[Unknown TopologyEvent]";
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700294 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700295
296 return "[TopologyEvent " + eventStr + " from " +
297 onosInstanceId.toString() + "]";
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800298 }
299
300 /**
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700301 * Gets the Topology event ID as a byte array.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800302 *
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700303 * @return the Topology event ID as a byte array.
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800304 */
305 public byte[] getID() {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700306 return getIDasByteBuffer().array();
307 }
308
309 /**
310 * Gets the Topology event ID as a ByteBuffer.
311 *
312 * @return the Topology event ID as a ByteBuffer.
313 */
314 public ByteBuffer getIDasByteBuffer() {
315 ByteBuffer eventId = null;
316
317 //
318 // Get the Event ID
319 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700320 idLabel: {
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700321 if (mastershipEvent != null) {
322 eventId = mastershipEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700323 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700324 }
325 if (switchEvent != null) {
326 eventId = switchEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700327 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700328 }
329 if (portEvent != null) {
330 eventId = portEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700331 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700332 }
333 if (linkEvent != null) {
334 eventId = linkEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700335 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700336 }
337 if (hostEvent != null) {
338 eventId = hostEvent.getIDasByteBuffer();
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700339 break idLabel;
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700340 }
Pavlin Radoslavov054cd592014-08-07 20:57:16 -0700341 // Test whether this is NO-OP event
342 if (onosInstanceId != null) {
343 String id = "NO-OP";
344 eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
345 break idLabel;
346 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700347 // No event found
348 throw new IllegalStateException("Invalid TopologyEvent ID");
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700349 }
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700350
351 //
352 // Prepare the ONOS Instance ID. The '@' separator is needed to avoid
353 // potential key collisions.
354 //
Pavlin Radoslavov845ffdd2014-08-06 18:01:26 -0700355 byte[] onosId =
356 ("@" + onosInstanceId.toString()).getBytes(StandardCharsets.UTF_8);
Pavlin Radoslavovcac157d2014-07-31 13:54:08 -0700357
358 // Concatenate the IDs
359 ByteBuffer buf =
360 ByteBuffer.allocate(eventId.capacity() + onosId.length);
361 buf.put(eventId);
362 buf.put(onosId);
363 buf.flip();
364 return buf;
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800365 }
Pavlin Radoslavov45ec04b2014-02-14 23:29:33 -0800366}