/* * Copyright (c) 2011,2012 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. * * This file incorporates work covered by the following copyright and * permission notice: * * Originally created by David Erickson, Stanford University * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an "AS * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language * governing permissions and limitations under the License. */ package org.opendaylight.controller.hosttracker; import java.net.InetAddress; import java.util.Date; import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.utils.NetUtils; /** * An entity on the network is a visible trace of a device that corresponds to a * packet received from a particular interface on the edge of a network, with a * particular VLAN tag, and a particular MAC address, along with any other * packet characteristics we might want to consider as helpful for * disambiguating devices. * * Entities are the most basic element of devices; devices consist of one or * more entities. Entities are immutable once created, except for the last seen * timestamp. * * @author readams * */ public class Entity implements Comparable { /** * Timeout for computing {@link Entity#activeSince}. * * @see {@link Entity#activeSince} */ protected static int ACTIVITY_TIMEOUT = 30000; /** * The MAC address associated with this entity */ protected long macAddress; /** * The IP address associated with this entity, or null if no IP learned from * the network observation associated with this entity */ protected Integer ipv4Address; /** * The VLAN tag on this entity, or null if untagged */ protected Short vlan; /** * The attachment point for this entity */ NodeConnector port; /** * The last time we observed this entity on the network */ protected Date lastSeenTimestamp; /** * The time between {@link Entity#activeSince} and * {@link Entity#lastSeenTimestamp} is a period of activity for this entity * where it was observed repeatedly. If, when the entity is observed, the is * longer ago than the activity timeout, {@link Entity#lastSeenTimestamp} * and {@link Entity#activeSince} will be set to the current time. */ protected Date activeSince; private int hashCode = 0; // ************ // Constructors // ************ /** * Create a new entity * * @param macAddress * @param vlan * @param ipv4Address * @param switchDPID * @param switchPort * @param lastSeenTimestamp */ public Entity(long macAddress, Short vlan, Integer ipv4Address, NodeConnector port, Date lastSeenTimestamp) { this.macAddress = macAddress; this.ipv4Address = ipv4Address; this.vlan = vlan; this.port = port; this.lastSeenTimestamp = lastSeenTimestamp; this.activeSince = lastSeenTimestamp; } // *************** // Getters/Setters // *************** // @JsonSerialize(using=MACSerializer.class) public long getMacAddress() { return macAddress; } // @JsonSerialize(using=IPv4Serializer.class) public Integer getIpv4Address() { return ipv4Address; } public Short getVlan() { return vlan; } public NodeConnector getPort() { return port; } // @JsonIgnore public boolean hasSwitchPort() { return port != null; } public Date getLastSeenTimestamp() { return lastSeenTimestamp; } /** * Set the last seen timestamp and also update {@link Entity#activeSince} if * appropriate * * @param lastSeenTimestamp * the new last seen timestamp * @see {@link Entity#activeSince} */ public void setLastSeenTimestamp(Date lastSeenTimestamp) { if (activeSince == null || (activeSince.getTime() + ACTIVITY_TIMEOUT) < lastSeenTimestamp .getTime()) { this.activeSince = lastSeenTimestamp; } this.lastSeenTimestamp = lastSeenTimestamp; } public Date getActiveSince() { return activeSince; } public void setActiveSince(Date activeSince) { this.activeSince = activeSince; } @Override public int hashCode() { if (hashCode != 0) { return hashCode; } final int prime = 31; hashCode = 1; hashCode = prime * hashCode + ((ipv4Address == null) ? 0 : ipv4Address.hashCode()); hashCode = prime * hashCode + (int) (macAddress ^ (macAddress >>> 32)); hashCode = prime * hashCode + ((port == null) ? 0 : port.hashCode()); hashCode = prime * hashCode + ((vlan == null) ? 0 : vlan.hashCode()); return hashCode; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (getClass() != obj.getClass()) { return false; } Entity other = (Entity) obj; if (ipv4Address == null) { if (other.ipv4Address != null) { return false; } } else if (!ipv4Address.equals(other.ipv4Address)) { return false; } if (macAddress != other.macAddress) { return false; } if (port == null) { if (other.port != null) { return false; } } else if (!port.equals(other.port)) { return false; } if (vlan == null) { if (other.vlan != null) { return false; } } else if (!vlan.equals(other.vlan)) { return false; } return true; } public HostNodeConnector toHostNodeConnector() { try { NodeConnector n = this.getPort(); InetAddress ip = InetAddress.getByAddress(NetUtils.intToByteArray4(this.getIpv4Address())); byte[] macAddr = NetUtils.longToByteArray6(this.getMacAddress()); HostNodeConnector nc = new HostNodeConnector(macAddr, ip, n, (short) 0); return nc; } catch (Exception e) { return null; } } @Override public String toString() { return "Entity [macAddress=" + macAddress + ", ipv4Address=" + ipv4Address + ", vlan=" + vlan + ", port=" + port + "]"; } @SuppressWarnings({ "rawtypes", "unchecked" }) @Override public int compareTo(Entity o) { int r; if (port == null) { r = o.port == null ? 0 : -1; } else if (o.port == null) { r = 1; } else { // XXX - the node id is only defined as an object rather // than something useful. We're just going to have to // blindly cast to Comparable and hope it works. Comparable switchId = (Comparable) port.getNode().getID(); Comparable oswitchId = (Comparable) o.port.getNode().getID(); r = switchId.compareTo(oswitchId); if (r != 0) { return r; } Comparable portId = (Comparable) port.getID(); Comparable oportId = (Comparable) o.port.getID(); r = portId.compareTo(oportId); } return r; } }