blob: 82fa6e54f340be67b93af928b86049af7eff6b4a [file] [log] [blame]
package net.onrc.onos.core.topology;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.OnosInstanceId;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Self-contained Topology event Object
* <p/>
* TODO: For now the topology event contains one of the following events:
* Switch Mastership, Switch, Port, Link, Host. In the future it will contain
* multiple events in a single transaction.
* TODO: This class should become immutable after its internals and usage
* are finalized.
*/
public final class TopologyEvent {
private final MastershipEvent mastershipEvent; // Set for Mastership event
private final SwitchEvent switchEvent; // Set for Switch event
private final PortEvent portEvent; // Set for Port event
private final LinkEvent linkEvent; // Set for Link event
private final HostEvent hostEvent; // Set for Host event
private final OnosInstanceId onosInstanceId; // The ONOS Instance ID
/**
* Default constructor for serializer.
*/
@Deprecated
protected TopologyEvent() {
mastershipEvent = null;
switchEvent = null;
portEvent = null;
linkEvent = null;
hostEvent = null;
onosInstanceId = null;
}
/**
* Constructor for creating an empty (NO-OP) Topology Event.
*
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
protected TopologyEvent(OnosInstanceId onosInstanceId) {
mastershipEvent = null;
switchEvent = null;
portEvent = null;
linkEvent = null;
hostEvent = null;
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Constructor for given Switch Mastership event.
*
* @param mastershipEvent the Switch Mastership event to use.
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
TopologyEvent(MastershipEvent mastershipEvent,
OnosInstanceId onosInstanceId) {
this.mastershipEvent = checkNotNull(mastershipEvent);
this.switchEvent = null;
this.portEvent = null;
this.linkEvent = null;
this.hostEvent = null;
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Constructor for given Switch event.
*
* @param switchEvent the Switch event to use.
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
TopologyEvent(SwitchEvent switchEvent, OnosInstanceId onosInstanceId) {
this.mastershipEvent = null;
this.switchEvent = checkNotNull(switchEvent);
this.portEvent = null;
this.linkEvent = null;
this.hostEvent = null;
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Constructor for given Port event.
*
* @param portEvent the Port event to use.
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
TopologyEvent(PortEvent portEvent, OnosInstanceId onosInstanceId) {
this.mastershipEvent = null;
this.switchEvent = null;
this.portEvent = checkNotNull(portEvent);
this.linkEvent = null;
this.hostEvent = null;
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Constructor for given Link event.
*
* @param linkEvent the Link event to use.
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
TopologyEvent(LinkEvent linkEvent, OnosInstanceId onosInstanceId) {
this.mastershipEvent = null;
this.switchEvent = null;
this.portEvent = null;
this.linkEvent = checkNotNull(linkEvent);
this.hostEvent = null;
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Constructor for given Host event.
*
* @param hostEvent the Host event to use.
* @param onosInstanceId the ONOS Instance ID that originates the event.
*/
TopologyEvent(HostEvent hostEvent, OnosInstanceId onosInstanceId) {
this.mastershipEvent = null;
this.switchEvent = null;
this.portEvent = null;
this.linkEvent = null;
this.hostEvent = checkNotNull(hostEvent);
this.onosInstanceId = checkNotNull(onosInstanceId);
}
/**
* Gets the Mastership event.
*
* @return the Mastership event.
*/
public MastershipEvent getMastershipEvent() {
return mastershipEvent;
}
/**
* Gets the Switch event.
*
* @return the Switch event.
*/
public SwitchEvent getSwitchEvent() {
return switchEvent;
}
/**
* Gets the Port event.
*
* @return the Port event.
*/
public PortEvent getPortEvent() {
return portEvent;
}
/**
* Gets the Link event.
*
* @return the Link event.
*/
public LinkEvent getLinkEvent() {
return linkEvent;
}
/**
* Gets the Host event.
*
* @return the Host event.
*/
public HostEvent getHostEvent() {
return hostEvent;
}
/**
* Gets the ONOS Instance ID.
*
* @return the ONOS Instance ID.
*/
public OnosInstanceId getOnosInstanceId() {
return onosInstanceId;
}
/**
* Gets the event origin DPID.
*
* @return the event origin DPID.
*/
public Dpid getOriginDpid() {
if (mastershipEvent != null) {
return mastershipEvent.getOriginDpid();
}
if (switchEvent != null) {
return switchEvent.getOriginDpid();
}
if (portEvent != null) {
return portEvent.getOriginDpid();
}
if (linkEvent != null) {
return linkEvent.getOriginDpid();
}
if (hostEvent != null) {
return hostEvent.getOriginDpid();
}
return null;
}
/**
* Tests whether the event origin DPID equals the specified DPID.
*
* @param dpid the DPID to compare against.
* @return true if the event origin Dpid equals the specified DPID.
*/
public boolean equalsOriginDpid(Dpid dpid) {
return dpid.equals(getOriginDpid());
}
/**
* Checks if all events contained are equal.
*
* @param obj TopologyEvent to compare against
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TopologyEvent other = (TopologyEvent) obj;
return Objects.equals(mastershipEvent, other.mastershipEvent) &&
Objects.equals(switchEvent, other.switchEvent) &&
Objects.equals(portEvent, other.portEvent) &&
Objects.equals(linkEvent, other.linkEvent) &&
Objects.equals(hostEvent, other.hostEvent) &&
Objects.equals(onosInstanceId, other.onosInstanceId);
}
@Override
public int hashCode() {
return Objects.hash(mastershipEvent, switchEvent, portEvent,
linkEvent, hostEvent, onosInstanceId);
}
/**
* Gets the string representation of the event.
*
* @return the string representation of the event.
*/
@Override
public String toString() {
String eventStr = null;
//
// Get the Event string
//
stringLabel: {
if (mastershipEvent != null) {
eventStr = mastershipEvent.toString();
break stringLabel;
}
if (switchEvent != null) {
eventStr = switchEvent.toString();
break stringLabel;
}
if (portEvent != null) {
eventStr = portEvent.toString();
break stringLabel;
}
if (linkEvent != null) {
eventStr = linkEvent.toString();
break stringLabel;
}
if (hostEvent != null) {
eventStr = hostEvent.toString();
break stringLabel;
}
// Test whether this is NO-OP event
if (onosInstanceId != null) {
eventStr = "NO-OP";
break stringLabel;
}
// No event found
return "[Unknown TopologyEvent]";
}
return "[TopologyEvent " + eventStr + " from " +
onosInstanceId.toString() + "]";
}
/**
* Gets the Topology event ID as a byte array.
*
* @return the Topology event ID as a byte array.
*/
public byte[] getID() {
return getIDasByteBuffer().array();
}
/**
* Gets the Topology event ID as a ByteBuffer.
*
* @return the Topology event ID as a ByteBuffer.
*/
public ByteBuffer getIDasByteBuffer() {
ByteBuffer eventId = null;
//
// Get the Event ID
//
idLabel: {
if (mastershipEvent != null) {
eventId = mastershipEvent.getIDasByteBuffer();
break idLabel;
}
if (switchEvent != null) {
eventId = switchEvent.getIDasByteBuffer();
break idLabel;
}
if (portEvent != null) {
eventId = portEvent.getIDasByteBuffer();
break idLabel;
}
if (linkEvent != null) {
eventId = linkEvent.getIDasByteBuffer();
break idLabel;
}
if (hostEvent != null) {
eventId = hostEvent.getIDasByteBuffer();
break idLabel;
}
// Test whether this is NO-OP event
if (onosInstanceId != null) {
String id = "NO-OP";
eventId = ByteBuffer.wrap(id.getBytes(StandardCharsets.UTF_8));
break idLabel;
}
// No event found
throw new IllegalStateException("Invalid TopologyEvent ID");
}
//
// Prepare the ONOS Instance ID. The '@' separator is needed to avoid
// potential key collisions.
//
byte[] onosId =
("@" + onosInstanceId.toString()).getBytes(StandardCharsets.UTF_8);
// Concatenate the IDs
ByteBuffer buf =
ByteBuffer.allocate(eventId.capacity() + onosId.length);
buf.put(eventId);
buf.put(onosId);
buf.flip();
return buf;
}
}