package net.onrc.onos.core.topology; import static com.google.common.base.Preconditions.checkNotNull; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Objects; import net.floodlightcontroller.util.MACAddress; import net.onrc.onos.core.topology.web.serializers.HostDataSerializer; import net.onrc.onos.core.util.Dpid; import net.onrc.onos.core.util.SwitchPort; import org.codehaus.jackson.map.annotate.JsonSerialize; /** * Self-contained Host object. */ @JsonSerialize(using = HostDataSerializer.class) public class HostData extends TopologyElement<HostData> { private final MACAddress mac; private final int ip; private List<SwitchPort> attachmentPoints; private long lastSeenTime; /** * Default constructor for Serializer to use. */ @Deprecated protected HostData() { mac = null; ip = 0; } /** * Constructor for a given host MAC address. * * @param mac the MAC address to identify the host */ public HostData(MACAddress mac) { this.mac = checkNotNull(mac); this.ip = 0; this.attachmentPoints = new LinkedList<>(); } /** * Constructor for a given host MAC address. * * @param mac the MAC address to identify the host */ public HostData(MACAddress mac, int ip) { this.mac = checkNotNull(mac); this.ip = ip; this.attachmentPoints = new LinkedList<>(); } /** * Copy constructor. * <p> * Creates an unfrozen copy of the given HostData object. * * @param original the object to make copy of */ public HostData(HostData original) { super(original); this.mac = original.mac; this.ip = original.ip; this.attachmentPoints = new ArrayList<>(original.attachmentPoints); this.lastSeenTime = original.lastSeenTime; } /** * Gets the host MAC address. * * @return the MAC address. */ public MACAddress getMac() { return mac; } /** * Gets the host IP address. * * @return the IP address. */ public int getIp() { return ip; } /** * Gets the switch attachment points. * * @return the switch attachment points */ public List<SwitchPort> getAttachmentPoints() { return Collections.unmodifiableList(attachmentPoints); } /** * Sets the switch attachment points. * * @param attachmentPoints the switch attachment points to set */ public void setAttachmentPoints(List<SwitchPort> attachmentPoints) { if (isFrozen()) { throw new IllegalStateException("Tried to modify frozen instance: " + this); } this.attachmentPoints = attachmentPoints; } /** * Adds a switch attachment point. * * @param attachmentPoint the switch attachment point to add */ public void addAttachmentPoint(SwitchPort attachmentPoint) { if (isFrozen()) { throw new IllegalStateException("Tried to modify frozen instance: " + this); } // may need to maintain uniqueness this.attachmentPoints.add(0, attachmentPoint); } /** * Removes a switch attachment point. * * @param attachmentPoint the switch attachment point to remove */ public boolean removeAttachmentPoint(SwitchPort attachmentPoint) { if (isFrozen()) { throw new IllegalStateException("Tried to modify frozen instance: " + this); } return this.attachmentPoints.remove(attachmentPoint); } /** * Gets the host last seen time in milliseconds since the epoch. * * @return the host last seen time in milliseconds since the epoch */ public long getLastSeenTime() { return lastSeenTime; } /** * Sets the host last seen time in milliseconds since the epoch. * * @param lastSeenTime the host last seen time in milliseconds since the * epoch */ public void setLastSeenTime(long lastSeenTime) { if (isFrozen()) { throw new IllegalStateException("Tried to modify frozen instance: " + this); } this.lastSeenTime = lastSeenTime; } /** * Computes the host ID for a given host MAC address. * <p> * TODO: This method should be replaced with a method that uses * MACAddress as an argument instead of a byte array. * * @param mac the host MAC address to use * @return the host ID as a ByteBuffer */ public static ByteBuffer getHostID(final byte[] mac) { return (ByteBuffer) ByteBuffer.allocate(2 + mac.length) .putChar('H').put(mac).flip(); } @Override public Dpid getOriginDpid() { // TODO: Eventually, we should return a collection of Dpid values for (SwitchPort sp : attachmentPoints) { return sp.getDpid(); } return null; } @Override public ByteBuffer getIDasByteBuffer() { return getHostID(mac.toBytes()); } @Override public int hashCode() { return 31 * super.hashCode() + Objects.hash(attachmentPoints, mac); } @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } // Compare attributes if (!super.equals(o)) { return false; } HostData other = (HostData) o; // XXX lastSeenTime excluded from Equality condition, is it OK? return Objects.equals(mac, other.mac) && ip == other.ip && Objects.equals(this.attachmentPoints, other.attachmentPoints); } @Override public String toString() { return "[HostData " + mac + "(ip:" + ip + ")" + " attachmentPoints:" + attachmentPoints + "]"; } }