HostTracker StaticHost changes
[controller.git] / opendaylight / hosttracker_new / implementation / src / main / java / org / opendaylight / controller / hosttracker / internal / DeviceManagerImpl.java
index 8435a94f5836c28db029001574b37b076f575163..faf9416934f897dd77bafda31ea565d4c75742e7 100755 (executable)
@@ -37,6 +37,8 @@ import static org.opendaylight.controller.hosttracker.internal.DeviceManagerImpl
 import static org.opendaylight.controller.hosttracker.internal.DeviceManagerImpl.DeviceUpdate.Change.CHANGE;
 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;
@@ -54,6 +56,7 @@ import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 
@@ -64,7 +67,10 @@ import org.opendaylight.controller.hosttracker.IDeviceService;
 import org.opendaylight.controller.hosttracker.IEntityClass;
 import org.opendaylight.controller.hosttracker.IEntityClassListener;
 import org.opendaylight.controller.hosttracker.IEntityClassifierService;
+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.Edge;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
@@ -76,9 +82,12 @@ 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.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.SingletonTask;
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
 import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
@@ -93,7 +102,7 @@ import org.slf4j.LoggerFactory;
  * @author readams
  */
 public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
-        IListenDataPacket, ITopologyManagerAware {
+        IListenDataPacket, ITopologyManagerAware, IfIptoHost {
     protected static Logger logger = LoggerFactory
             .getLogger(DeviceManagerImpl.class);
 
@@ -285,6 +294,10 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
      */
     protected ListenerDispatcher<String, IDeviceListener> deviceListeners;
 
+    /**
+     * Using the IfNewHostNotify to notify listeners of host changes.
+     */
+    private Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
     /**
      * A device update event to be dispatched
      */
@@ -424,6 +437,14 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
     // Dependency injection
     // ********************
 
+    void setNewHostNotify(IfNewHostNotify obj){
+        this.newHostNotify.add(obj);
+    }
+
+    void unsetNewHostNotify(IfNewHostNotify obj){
+        this.newHostNotify.remove(obj);
+    }
+
     void setDataPacketService(IDataPacketService s) {
         this.dataPacketService = s;
     }
@@ -534,6 +555,18 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
     // IDeviceManagerService
     // *********************
 
+    void setSwitchManager(ISwitchManager s) {
+        logger.debug("SwitchManager set");
+        this.switchManager = s;
+    }
+
+    void unsetSwitchManager(ISwitchManager s) {
+        if (this.switchManager == s) {
+            logger.debug("SwitchManager removed!");
+            this.switchManager = null;
+        }
+    }
+
     @Override
     public IDevice getDevice(Long deviceKey) {
         return deviceMap.get(deviceKey);
@@ -763,11 +796,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;
@@ -1149,6 +1182,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         logger.info("Primary index {}", primaryIndex);
         ArrayList<Long> deleteQueue = null;
         LinkedList<DeviceUpdate> deviceUpdates = null;
+        Device oldDevice = null;
         Device device = null;
 
         // we may need to restart the learning process if we detect
@@ -1304,7 +1338,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
                 // modified this Device).
                 if (!res)
                     continue;
-
+                oldDevice = device;
                 device = newDevice;
                 // update indices
                 if (!updateIndices(device, deviceKey)) {
@@ -1333,7 +1367,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,
@@ -1427,9 +1461,32 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
 
     protected void notifyListeners(List<IDeviceListener> listeners,
             DeviceUpdate update) {
-        if (listeners == 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.
+         */
+
+        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:
+            }
+        }
+
+        /**
+         * TODO: Remove this section as IDeviceListener functionality gets
+         * merged with IfNewHostNotify
+         */
         for (IDeviceListener listener : listeners) {
             switch (update.change) {
             case ADD:
@@ -1849,6 +1906,19 @@ 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 -
@@ -2043,6 +2113,103 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
          */
     }
 
+    @Override
+    public HostNodeConnector hostFind(InetAddress networkAddress) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public HostNodeConnector hostQuery(InetAddress networkAddress) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public List<List<String>> getHostNetworkHierarchy(InetAddress hostAddress) {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Set<HostNodeConnector> getAllHosts() {
+        Collection<Device> devices = Collections
+                .unmodifiableCollection(deviceMap.values());
+        Iterator<Device> i = devices.iterator();
+        Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
+        while (i.hasNext()) {
+            Device device = i.next();
+            nc.add(device.toHostNodeConnector());
+        }
+        return nc;
+    }
+
+    @Override
+    public Set<HostNodeConnector> getActiveStaticHosts() {
+        Collection<Device> devices = Collections
+                .unmodifiableCollection(deviceMap.values());
+        Iterator<Device> i = devices.iterator();
+        Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
+        while (i.hasNext()) {
+            Device device = i.next();
+            if(device.isStaticHost())
+                nc.add(device.toHostNodeConnector());
+        }
+        return nc;
+    }
+
+    @Override
+    public Set<HostNodeConnector> getInactiveStaticHosts() {
+        // TODO Auto-generated method stub
+        return null;
+    }
+
+    @Override
+    public Status addStaticHost(String networkAddress, String dataLayerAddress,
+            NodeConnector nc, String vlan) {
+        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());
+            Device d = this.learnDeviceByEntity(e);
+            d.setStaticHost(true);
+            return new Status(StatusCode.SUCCESS);
+        }catch(UnknownHostException e){
+            return new Status(StatusCode.INTERNALERROR);
+        }
+    }
+
+    @Override
+    public Status removeStaticHost(String networkAddress) {
+        Integer addr;
+        try {
+            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()){
+            Device d = di.next();
+            if(d.isStaticHost()){
+                deleteDevice(d);
+                for (IfNewHostNotify notify : newHostNotify)
+                    notify.notifyHTClientHostRemoved(d.toHostNodeConnector());
+                for (IDeviceListener listener : listeners)
+                        listener.deviceRemoved(d);
+            }
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
     /**
      * For testing: consolidate the store NOW
      */