X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fhosttracker_new%2Fimplementation%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fhosttracker%2Finternal%2FDeviceManagerImpl.java;h=95d33ceef90fcaf019cead9ffe9a2a97858e8e47;hb=2f14a41bbd09010114116aef1499641f7251bf83;hp=0a70b72575dca0ca05bb0b599ed1ce88679e64e4;hpb=feeb64e96e1bfbb4d5492ddabcf70e7f43ad4082;p=controller.git diff --git a/opendaylight/hosttracker_new/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/DeviceManagerImpl.java b/opendaylight/hosttracker_new/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/DeviceManagerImpl.java index 0a70b72575..95d33ceef9 100755 --- a/opendaylight/hosttracker_new/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/DeviceManagerImpl.java +++ b/opendaylight/hosttracker_new/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/DeviceManagerImpl.java @@ -38,6 +38,7 @@ import static org.opendaylight.controller.hosttracker.internal.DeviceManagerImpl import static org.opendaylight.controller.hosttracker.internal.DeviceManagerImpl.DeviceUpdate.Change.DELETE; import java.net.InetAddress; +import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -51,6 +52,7 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Queue; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -70,9 +72,16 @@ import org.opendaylight.controller.hosttracker.IfIptoHost; import org.opendaylight.controller.hosttracker.IfNewHostNotify; import org.opendaylight.controller.hosttracker.SwitchPort; import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector; +import org.opendaylight.controller.sal.core.ConstructionException; import org.opendaylight.controller.sal.core.Edge; +import org.opendaylight.controller.sal.core.Host; +import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType; +import org.opendaylight.controller.sal.core.Property; +import org.opendaylight.controller.sal.core.State; +import org.opendaylight.controller.sal.core.Tier; +import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.packet.ARP; import org.opendaylight.controller.sal.packet.Ethernet; import org.opendaylight.controller.sal.packet.IDataPacketService; @@ -80,11 +89,17 @@ import org.opendaylight.controller.sal.packet.IListenDataPacket; import org.opendaylight.controller.sal.packet.Packet; import org.opendaylight.controller.sal.packet.PacketResult; import org.opendaylight.controller.sal.packet.RawPacket; +import org.opendaylight.controller.sal.packet.address.DataLinkAddress; +import org.opendaylight.controller.sal.packet.address.EthernetAddress; import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; +import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.ListenerDispatcher; import org.opendaylight.controller.sal.utils.MultiIterator; +import org.opendaylight.controller.sal.utils.NetUtils; import org.opendaylight.controller.sal.utils.SingletonTask; import org.opendaylight.controller.sal.utils.Status; +import org.opendaylight.controller.sal.utils.StatusCode; +import org.opendaylight.controller.switchmanager.IInventoryListener; import org.opendaylight.controller.switchmanager.ISwitchManager; import org.opendaylight.controller.topologymanager.ITopologyManager; import org.opendaylight.controller.topologymanager.ITopologyManagerAware; @@ -99,7 +114,8 @@ import org.slf4j.LoggerFactory; * @author readams */ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, - IListenDataPacket, ITopologyManagerAware, IfIptoHost { + IListenDataPacket, ITopologyManagerAware, IfIptoHost, + IInventoryListener { protected static Logger logger = LoggerFactory .getLogger(DeviceManagerImpl.class); @@ -211,6 +227,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, */ protected ConcurrentHashMap deviceMap; + protected ConcurrentHashMap inactiveStaticDevices; /** * Counter used to generate device keys */ @@ -294,7 +311,9 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, /** * Using the IfNewHostNotify to notify listeners of host changes. */ - private Set newHostNotify = Collections.synchronizedSet(new HashSet()); + private Set newHostNotify = Collections + .synchronizedSet(new HashSet()); + /** * A device update event to be dispatched */ @@ -434,11 +453,11 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, // Dependency injection // ******************** - void setNewHostNotify(IfNewHostNotify obj){ + void setNewHostNotify(IfNewHostNotify obj) { this.newHostNotify.add(obj); } - void unsetNewHostNotify(IfNewHostNotify obj){ + void unsetNewHostNotify(IfNewHostNotify obj) { this.newHostNotify.remove(obj); } @@ -485,6 +504,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, secondaryIndexMap = new HashMap, DeviceIndex>(); deviceMap = new ConcurrentHashMap(); + inactiveStaticDevices = new ConcurrentHashMap(); classStateMap = new ConcurrentHashMap(); apComparator = new AttachmentPointComparator(); @@ -793,11 +813,11 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, if (inPkt == null) { return PacketResult.IGNORED; } -// try { -// throw new Exception("Sample"); -// } catch (Exception e) { -// logger.error("Sample stack trace", e); -// } + // try { + // throw new Exception("Sample"); + // } catch (Exception e) { + // logger.error("Sample stack trace", e); + // } Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt); Ethernet eth; @@ -1179,6 +1199,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, logger.info("Primary index {}", primaryIndex); ArrayList deleteQueue = null; LinkedList deviceUpdates = null; + Device oldDevice = null; Device device = null; // we may need to restart the learning process if we detect @@ -1334,7 +1355,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, // modified this Device). if (!res) continue; - + oldDevice = device; device = newDevice; // update indices if (!updateIndices(device, deviceKey)) { @@ -1363,7 +1384,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, if (moved) { // we count device moved events in // sendDeviceMovedNotification() - sendDeviceMovedNotification(device); + sendDeviceMovedNotification(device, oldDevice); if (logger.isTraceEnabled()) { logger.trace("Device moved: attachment points {}," + "entities {}", device.attachmentPoints, @@ -1457,21 +1478,67 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, protected void notifyListeners(List listeners, DeviceUpdate update) { + // Topology update is for some reason outside of listeners registry + // logic + Entity[] ents = update.device.getEntities(); + Entity e = ents[ents.length - 1]; + + NodeConnector p = e.getPort(); + Node node = p.getNode(); + Host h = null; + try { + + byte[] mac = NetUtils.longToByteArray6(e.getMacAddress()); + DataLinkAddress dla = new EthernetAddress( + mac); + e.getIpv4Address(); + InetAddress.getAllByName(e.getIpv4Address().toString()); + h = new org.opendaylight.controller.sal.core.Host(dla, + InetAddress.getByName(e.getIpv4Address().toString())); + } catch (ConstructionException ce) { + p = null; + h = null; + } catch (UnknownHostException ue) { + p = null; + h = null; + } + + if (topology != null && p != null && h != null) { + if (update.change.equals(DeviceUpdate.Change.ADD)) { + Tier tier = new Tier(1); + switchManager.setNodeProp(node, tier); + topology.updateHostLink(p, h, UpdateType.ADDED, null); + } else { + // No need to reset the tiering if no other hosts are currently + // connected + // If this switch was discovered to be an access switch, it + // still is even if the host is down + Tier tier = new Tier(0); + switchManager.setNodeProp(node, tier); + topology.updateHostLink(p, h, UpdateType.REMOVED, null); + } + } + if (listeners == null && newHostNotify.isEmpty()) { return; } /** - * TODO: IfNewHostNotify is needed for current controller API. - * Adding logic so that existing apps (like SimpleForwardingManager) - * work. IDeviceListener adds additional methods and uses IListener's - * callback ordering. The two interfaces need to be merged. + * TODO: IfNewHostNotify is needed for current controller API. Adding + * logic so that existing apps (like SimpleForwardingManager) work. + * IDeviceListener adds additional methods and uses IListener's callback + * ordering. The two interfaces need to be merged. */ - for (IfNewHostNotify notify : newHostNotify){ + for (IfNewHostNotify notify : newHostNotify) { switch (update.change) { case ADD: notify.notifyHTClient(update.device.toHostNodeConnector()); break; + case DELETE: + notify.notifyHTClientHostRemoved(update.device + .toHostNodeConnector()); + break; + case CHANGE: } } @@ -1899,6 +1966,21 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, } } + /** + * Send update notifications to listeners. IfNewHostNotify listeners need to + * remove old device and add new device. + * + * @param device + * @param oldDevice + */ + protected void sendDeviceMovedNotification(Device device, Device oldDevice) { + for (IfNewHostNotify notify : newHostNotify) { + notify.notifyHTClientHostRemoved(oldDevice.toHostNodeConnector()); + notify.notifyHTClient(device.toHostNodeConnector()); + } + sendDeviceMovedNotification(device); + } + /** * this method will reclassify and reconcile a device - possibilities are - * create new device(s), remove entities from this device. If the device @@ -1973,7 +2055,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, return mac; } - /** + /** * Accepts an IPv4 address in a byte array and returns the corresponding * 32-bit integer value. * @@ -2131,29 +2213,176 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener, @Override public Set getActiveStaticHosts() { - // TODO Auto-generated method stub - return null; + Collection devices = Collections + .unmodifiableCollection(deviceMap.values()); + Iterator i = devices.iterator(); + Set nc = new HashSet(); + while (i.hasNext()) { + Device device = i.next(); + if (device.isStaticHost()) + nc.add(device.toHostNodeConnector()); + } + return nc; } @Override public Set getInactiveStaticHosts() { - // TODO Auto-generated method stub - return null; + Collection devices = Collections + .unmodifiableCollection(inactiveStaticDevices.values()); + Iterator i = devices.iterator(); + Set nc = new HashSet(); + while (i.hasNext()) { + Entity ent = i.next(); + nc.add(ent.toHostNodeConnector()); + + } + return nc; } @Override public Status addStaticHost(String networkAddress, String dataLayerAddress, NodeConnector nc, String vlan) { - // TODO Auto-generated method stub - return null; + Long mac = HexEncode.stringToLong(dataLayerAddress); + try { + InetAddress addr = InetAddress.getByName(networkAddress); + int ip = toIPv4Address(addr.getAddress()); + Entity e = new Entity(mac, Short.valueOf(vlan), ip, nc, new Date()); + + if (switchManager.isNodeConnectorEnabled(e.getPort())) { + Device d = this.learnDeviceByEntity(e); + d.setStaticHost(true); + } else { + logger.debug( + "Switch or switchport is not up, adding host {} to inactive list", + addr.getHostName()); + inactiveStaticDevices.put(e.getPort(), e); + } + return new Status(StatusCode.SUCCESS); + } catch (UnknownHostException e) { + return new Status(StatusCode.INTERNALERROR); + } } @Override public Status removeStaticHost(String networkAddress) { - // TODO Auto-generated method stub - return null; + Integer addr; + try { + addr = toIPv4Address(InetAddress.getByName(networkAddress) + .getAddress()); + } catch (UnknownHostException e) { + return new Status(StatusCode.NOTFOUND, "Host does not exist"); + } + Iterator di = this.getDeviceIteratorForQuery(null, null, addr, + null); + List listeners = deviceListeners.getOrderedListeners(); + while (di.hasNext()) { + Device d = di.next(); + if (d.isStaticHost()) { + deleteDevice(d); + for (IfNewHostNotify notify : newHostNotify) + notify.notifyHTClientHostRemoved(d.toHostNodeConnector()); + for (IDeviceListener listener : listeners) + listener.deviceRemoved(d); + } + } + //go through inactive entites. + Set inactive = this.getInactiveStaticHosts(); + for(HostNodeConnector nc : inactive){ + Integer ip =toIPv4Address(nc.getNetworkAddress().getAddress()); + if(ip.equals(addr)){ + this.inactiveStaticDevices.remove(nc.getnodeConnector()); + } + } + + + return new Status(StatusCode.SUCCESS); + } + + @Override + public void notifyNode(Node node, UpdateType type, + Map propMap) { + if (node == null) + return; + List listeners = deviceListeners.getOrderedListeners(); + switch (type) { + case REMOVED: + logger.debug("Received removed node {}", node); + for (Entry d : deviceMap.entrySet()) { + Device device = d.getValue(); + HostNodeConnector host = device.toHostNodeConnector(); + if (host.getnodeconnectorNode().equals(node)) { + logger.debug("Node: {} is down, remove from Hosts_DB", node); + deleteDevice(device); + for (IfNewHostNotify notify : newHostNotify) + notify.notifyHTClientHostRemoved(host); + for (IDeviceListener listener : listeners) + listener.deviceRemoved(device); + } + } + break; + default: + break; + } } + @Override + public void notifyNodeConnector(NodeConnector nodeConnector, + UpdateType type, Map propMap) { + if (nodeConnector == null) + return; + List listeners = deviceListeners.getOrderedListeners(); + boolean up = false; + switch (type) { + case ADDED: + up = true; + break; + case REMOVED: + break; + case CHANGED: + State state = (State) propMap.get(State.StatePropName); + if ((state != null) && (state.getValue() == State.EDGE_UP)) { + up = true; + } + break; + default: + return; + } + + if (up) { + logger.debug("handleNodeConnectorStatusUp {}", nodeConnector); + + Entity ent = inactiveStaticDevices.get(nodeConnector); + Device device = this.learnDeviceByEntity(ent); + if(device!=null){ + HostNodeConnector host = device.toHostNodeConnector(); + if (host != null) { + inactiveStaticDevices.remove(nodeConnector); + for (IfNewHostNotify notify : newHostNotify) + notify.notifyHTClient(host); + for (IDeviceListener listener : listeners) + listener.deviceAdded(device); + } else { + logger.debug("handleNodeConnectorStatusDown {}", nodeConnector); + } + } + }else{ + // remove all devices on the node that went down. + for (Entry entry : deviceMap.entrySet()) { + Device device = entry.getValue(); + HostNodeConnector host = device.toHostNodeConnector(); + if (host.getnodeConnector().equals(nodeConnector)) { + deleteDevice(device); + for (IfNewHostNotify notify : newHostNotify) + notify.notifyHTClientHostRemoved(host); + for (IDeviceListener listener : listeners) + listener.deviceRemoved(device); + } + } + + } + } + + /** * For testing: consolidate the store NOW */