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;
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.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;
* @author readams
*/
public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
- IListenDataPacket, ITopologyManagerAware, IfIptoHost {
+ IListenDataPacket, ITopologyManagerAware, IfIptoHost,
+ IInventoryListener {
protected static Logger logger = LoggerFactory
.getLogger(DeviceManagerImpl.class);
*/
protected ConcurrentHashMap<Long, Device> deviceMap;
+ protected ConcurrentHashMap<NodeConnector, Entity> inactiveStaticDevices;
/**
* Counter used to generate device keys
*/
/**
* Using the IfNewHostNotify to notify listeners of host changes.
*/
- private Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
+ private Set<IfNewHostNotify> newHostNotify = Collections
+ .synchronizedSet(new HashSet<IfNewHostNotify>());
+
/**
* A device update event to be dispatched
*/
long newDomain = 0;
boolean newBD = false;
- if (oldDomain < newDomain)
- return -1;
- else if (oldDomain > newDomain)
+ if (oldDomain < newDomain) {
+ return -1;
+ } else if (oldDomain > newDomain) {
return 1;
-
+ }
// Give preference to OFPP_LOCAL always
if (!oldAP.getPort().getType().equals(NodeConnectorIDType.SWSTACK)
&& newAP.getPort().getType()
// 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);
}
secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
deviceMap = new ConcurrentHashMap<Long, Device>();
+ inactiveStaticDevices = new ConcurrentHashMap<NodeConnector, Entity>();
classStateMap = new ConcurrentHashMap<String, ClassState>();
apComparator = new AttachmentPointComparator();
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;
protected void notifyListeners(List<IDeviceListener> listeners,
DeviceUpdate update) {
- // Topology update is for some reason outside of listeners registry
- // logic
+ // Topology update is for some reason outside of listeners registry
+ // logic
Entity[] ents = update.device.getEntities();
- Entity e = ents[ents.length-1];
+ 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);
} catch (ConstructionException ce) {
p = null;
h = null;
- } catch (UnknownHostException ue){
+ } catch (UnknownHostException ue) {
p = null;
h = null;
}
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());
+ notify.notifyHTClientHostRemoved(update.device
+ .toHostNodeConnector());
break;
case CHANGE:
}
}
}
}
+
/**
- * Send update notifications to listeners.
- * IfNewHostNotify listeners need to remove old device and add new device.
+ * 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);
+ 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 -
return mac;
}
- /**
+ /**
* Accepts an IPv4 address in a byte array and returns the corresponding
* 32-bit integer value.
*
Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
while (i.hasNext()) {
Device device = i.next();
- if(device.isStaticHost())
+ if (device.isStaticHost())
nc.add(device.toHostNodeConnector());
}
return nc;
@Override
public Set<HostNodeConnector> getInactiveStaticHosts() {
- // TODO Auto-generated method stub
- return null;
+ Collection<Entity> devices = Collections
+ .unmodifiableCollection(inactiveStaticDevices.values());
+ Iterator<Entity> i = devices.iterator();
+ Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
+ 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) {
Long mac = HexEncode.stringToLong(dataLayerAddress);
- try{
+ try {
InetAddress addr = InetAddress.getByName(networkAddress);
int ip = toIPv4Address(addr.getAddress());
Entity e = new Entity(mac, Short.valueOf(vlan), ip, nc, new Date());
- Device d = this.learnDeviceByEntity(e);
- d.setStaticHost(true);
+
+ 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){
+ } catch (UnknownHostException e) {
return new Status(StatusCode.INTERNALERROR);
}
}
public Status removeStaticHost(String networkAddress) {
Integer addr;
try {
- addr = toIPv4Address(InetAddress.getByName(networkAddress).getAddress());
+ addr = toIPv4Address(InetAddress.getByName(networkAddress)
+ .getAddress());
} catch (UnknownHostException e) {
return new Status(StatusCode.NOTFOUND, "Host does not exist");
}
- Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr, null);
- List<IDeviceListener> listeners = deviceListeners
- .getOrderedListeners();
- while(di.hasNext()){
+ Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr,
+ null);
+ List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+ while (di.hasNext()) {
Device d = di.next();
- if(d.isStaticHost()){
+ if (d.isStaticHost()) {
deleteDevice(d);
for (IfNewHostNotify notify : newHostNotify)
notify.notifyHTClientHostRemoved(d.toHostNodeConnector());
for (IDeviceListener listener : listeners)
- listener.deviceRemoved(d);
+ listener.deviceRemoved(d);
}
}
+ //go through inactive entites.
+ Set<HostNodeConnector> 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<String, Property> propMap) {
+ if (node == null)
+ return;
+ List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+ switch (type) {
+ case REMOVED:
+ logger.debug("Received removed node {}", node);
+ for (Entry<Long, Device> 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<String, Property> propMap) {
+ if (nodeConnector == null)
+ return;
+ List<IDeviceListener> 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<Long, Device> 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
*/