- /**
- * For testing: consolidate the store NOW
- */
- // void scheduleConsolidateStoreNow() {
- // this.storeConsolidateTask.reschedule(0, TimeUnit.MILLISECONDS);
- // }
-
- // private class DeviceSyncManager {
- // // maps (opaque) deviceKey to the time in System.nanoTime() when we
- // // last wrote the device to the sync store
- // private ConcurrentMap<Long, Long> lastWriteTimes =
- // new ConcurrentHashMap<Long, Long>();
- //
- // /**
- // * Write the given device to storage if we are MASTER.
- // * Use this method if the device has significantly changed (e.g.,
- // * new AP, new IP, entities removed).
- // * @param d the device to store
- // */
- // public void storeDevice(Device d) {
- // if (!isMaster)
- // return;
- // if (d == null)
- // return;
- // long now = System.nanoTime();
- // writeUpdatedDeviceToStorage(d);
- // lastWriteTimes.put(d.getDeviceKey(), now);
- // }
- //
- // /**
- // * Write the given device to storage if we are MASTER and if the
- // * last write for the device was more than this.syncStoreIntervalNs
- // * time ago.
- // * Use this method to updated last active times in the store.
- // * @param d the device to store
- // */
- // public void storeDeviceThrottled(Device d) {
- // long intervalNs = syncStoreWriteIntervalMs*1000L*1000L;
- // if (!isMaster)
- // return;
- // if (d == null)
- // return;
- // long now = System.nanoTime();
- // Long last = lastWriteTimes.get(d.getDeviceKey());
- // if (last == null ||
- // now - last > intervalNs) {
- // writeUpdatedDeviceToStorage(d);
- // lastWriteTimes.put(d.getDeviceKey(), now);
- // } else {
- // debugCounters.updateCounter(CNT_DEVICE_STORE_THROTTLED);
- // }
- // }
- //
- // /**
- // * Remove the given device from the store. If only some entities have
- // * been removed the updated device should be written using
- // * {@link #storeDevice(Device)}
- // * @param d
- // */
- // public void removeDevice(Device d) {
- // if (!isMaster)
- // return;
- // // FIXME: could we have a problem with concurrent put to the
- // // hashMap? I.e., we write a stale entry to the map after the
- // // delete and now are left with an entry we'll never clean up
- // lastWriteTimes.remove(d.getDeviceKey());
- // try {
- // // TODO: should probably do versioned delete. OTOH, even
- // // if we accidentally delete, we'll write it again after
- // // the next entity ....
- // debugCounters.updateCounter(CNT_DEVICE_REMOVED_FROM_STORE);
- // storeClient.delete(DeviceSyncRepresentation.computeKey(d));
- // } catch(ObsoleteVersionException e) {
- // // FIXME
- // } catch (SyncException e) {
- // debugCounters.updateCounter(CNT_SYNC_EXCEPTION);
- // logger.error("Could not remove device " + d + " from store", e);
- // }
- // }
- //
- // /**
- // * Remove the given Versioned device from the store. If the device
- // * was locally modified ignore the delete request.
- // * @param syncedDeviceKey
- // */
- // private void removeDevice(Versioned<DeviceSyncRepresentation> dev) {
- // try {
- // debugCounters.updateCounter(CNT_DEVICE_REMOVED_FROM_STORE);
- // storeClient.delete(dev.getValue().getKey(),
- // dev.getVersion());
- // } catch(ObsoleteVersionException e) {
- // // Key was locally modified by another thread.
- // // Do not delete and ignore.
- // } catch(SyncException e) {
- // debugCounters.updateCounter(CNT_SYNC_EXCEPTION);
- // logger.error("Failed to remove device entry for " +
- // dev.toString() + " from store.", e);
- // }
- // }
- //
- // /**
- // * Synchronously transition from SLAVE to MASTER. By iterating through
- // * the store and learning all devices from the store
- // */
- // private void goToMaster() {
- // if (logger.isDebugEnabled()) {
- // logger.debug("Transitioning to MASTER role");
- // }
- // debugCounters.updateCounter(CNT_TRANSITION_TO_MASTER);
- // IClosableIterator<Map.Entry<String,Versioned<DeviceSyncRepresentation>>>
- // iter = null;
- // try {
- // iter = storeClient.entries();
- // } catch (SyncException e) {
- // debugCounters.updateCounter(CNT_SYNC_EXCEPTION);
- // logger.error("Failed to read devices from sync store", e);
- // return;
- // }
- // try {
- // while(iter.hasNext()) {
- // Versioned<DeviceSyncRepresentation> versionedDevice =
- // iter.next().getValue();
- // DeviceSyncRepresentation storedDevice =
- // versionedDevice.getValue();
- // if (storedDevice == null)
- // continue;
- // debugCounters.updateCounter(CNT_DEVICES_FROM_STORE);
- // for(SyncEntity se: storedDevice.getEntities()) {
- // learnDeviceByEntity(se.asEntity());
- // }
- // }
- // } finally {
- // if (iter != null)
- // iter.close();
- // }
- // storeConsolidateTask.reschedule(initialSyncStoreConsolidateMs,
- // TimeUnit.MILLISECONDS);
- // }
- //
- // /**
- // * Actually perform the write of the device to the store
- // * FIXME: concurrent modification behavior
- // * @param device The device to write
- // */
- // private void writeUpdatedDeviceToStorage(Device device) {
- // try {
- // debugCounters.updateCounter(CNT_DEVICE_STORED);
- // // FIXME: use a versioned put
- // DeviceSyncRepresentation storeDevice =
- // new DeviceSyncRepresentation(device);
- // storeClient.put(storeDevice.getKey(), storeDevice);
- // } catch (ObsoleteVersionException e) {
- // // FIXME: what's the right behavior here. Can the store client
- // // even throw this error?
- // } catch (SyncException e) {
- // debugCounters.updateCounter(CNT_SYNC_EXCEPTION);
- // logger.error("Could not write device " + device +
- // " to sync store:", e);
- // }
- // }
- //
- // /**
- // * Iterate through all entries in the sync store. For each device
- // * in the store check if any stored entity matches a live device. If
- // * no entities match a live device we remove the entry from the store.
- // *
- // * Note: we do not check if all devices known to device manager are
- // * in the store. We rely on regular packetIns for that.
- // * Note: it's possible that multiple entries in the store map to the
- // * same device. We don't check or handle this case.
- // *
- // * We need to perform this check after a SLAVE->MASTER transition to
- // * get rid of all entries the old master might have written to the
- // * store after we took over. We also run it regularly in MASTER
- // * state to ensure we don't have stale entries in the store
- // */
- // private void consolidateStore() {
- // if (!isMaster)
- // return;
- // debugCounters.updateCounter(CNT_CONSOLIDATE_STORE_RUNS);
- // if (logger.isDebugEnabled()) {
- // logger.debug("Running consolidateStore.");
- // }
- // IClosableIterator<Map.Entry<String,Versioned<DeviceSyncRepresentation>>>
- // iter = null;
- // try {
- // iter = storeClient.entries();
- // } catch (SyncException e) {
- // debugCounters.updateCounter(CNT_SYNC_EXCEPTION);
- // logger.error("Failed to read devices from sync store", e);
- // return;
- // }
- // try {
- // while(iter.hasNext()) {
- // boolean found = false;
- // Versioned<DeviceSyncRepresentation> versionedDevice =
- // iter.next().getValue();
- // DeviceSyncRepresentation storedDevice =
- // versionedDevice.getValue();
- // if (storedDevice == null)
- // continue;
- // for(SyncEntity se: storedDevice.getEntities()) {
- // try {
- // // Do we have a device for this entity??
- // IDevice d = findDevice(se.macAddress, se.vlan,
- // se.ipv4Address,
- // se.switchDPID,
- // se.switchPort);
- // if (d != null) {
- // found = true;
- // break;
- // }
- // } catch (IllegalArgumentException e) {
- // // not all key fields provided. Skip entity
- // }
- // }
- // if (!found) {
- // // We currently DO NOT have a live device that
- // // matches the current device from the store.
- // // Delete device from store.
- // if (logger.isDebugEnabled()) {
- // logger.debug("Removing device {} from store. No "
- // + "corresponding live device",
- // storedDevice.getKey());
- // }
- // debugCounters.updateCounter(CNT_CONSOLIDATE_STORE_DEVICES_REMOVED);
- // removeDevice(versionedDevice);
- // }
- // }
- // } finally {
- // if (iter != null)
- // iter.close();
- // }
- // }
- // }
- //
- //
- // /**
- // * For testing. Sets the syncService. Only call after init but before
- // * startUp. Used by MockDeviceManager
- // * @param syncService
- // */
- // protected void setSyncServiceIfNotSet(ISyncService syncService) {
- // if (this.syncService == null)
- // this.syncService = syncService;
- // }
+ @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() {
+ 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 {
+ 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) {
+ 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);
+ }
+ }
+ }
+ //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);
+ }
+ }
+ }
+
+ }
+ }
+