diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java index 5d482c48133e1c09d0945bbc2d2117472523ee54..ad29a947fbed2a3af94e24259fe58701f7c5e778 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceService.java @@ -189,17 +189,6 @@ public interface IDeviceService extends IFloodlightService { */ public void addListener(IDeviceListener listener); - - /** - * Flush and/or reclassify all entities in a class - * - * @param entityClass the class to flush. If null, flush all classes - * @param reclassify if true, begin an asynchronous task to reclassify the - * flushed entities - */ - public void flushEntityCache(IEntityClass entityClass, - boolean reclassify); - /** * Specify points in the network where attachment points are not to * be learned. diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java new file mode 100644 index 0000000000000000000000000000000000000000..6029af1b6c855460a45b502e4c4f568761fc648f --- /dev/null +++ b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassListener.java @@ -0,0 +1,35 @@ +/** +* Copyright 2011, Big Switch Networks, Inc. +* 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 net.floodlightcontroller.devicemanager; + +import java.util.Set; + +/** + * Implementors of this interface can receive updates from DeviceManager about + * the changes entity Classes. + * + * @author Ananth Suryanarayana (Ananth.Suryanarayana@bigswitch.com) + */ +public interface IEntityClassListener { + + /** + * Process entity classes change event. + * @param entityClassNames Set of entity classes changed + */ + public void entityClassChanged(Set<String> entityClassNames); +} diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java index 8d693ce9220155f92ef2aef5ecfec785eee78c84..2569a7df54ed892464810ca415b12a52d1ea76a7 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/IEntityClassifierService.java @@ -98,5 +98,11 @@ public interface IEntityClassifierService extends IFloodlightService { void deviceUpdate(IDevice oldDevice, Collection<? extends IDevice> newDevices); + /** + * Adds a listener to listen for IEntityClassifierServices notifications + * + * @param listener The listener that wants the notifications + */ + public void addListener(IEntityClassListener listener); } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java index 353a72d1b5b8a3e382feb895d6ac24e10bc9c8e8..948272a0c10a845edc33cf8b54a526aae5d7e8f6 100644 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DefaultEntityClassifier.java @@ -31,6 +31,7 @@ import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceService; import net.floodlightcontroller.devicemanager.IDeviceService.DeviceField; import net.floodlightcontroller.devicemanager.IEntityClass; +import net.floodlightcontroller.devicemanager.IEntityClassListener; import net.floodlightcontroller.devicemanager.IEntityClassifierService; /** @@ -46,6 +47,12 @@ public class DefaultEntityClassifier implements * A default fixed entity class */ protected static class DefaultEntityClass implements IEntityClass { + String name; + + public DefaultEntityClass(String name) { + this.name = name; + } + @Override public EnumSet<IDeviceService.DeviceField> getKeyFields() { return keyFields; @@ -53,7 +60,11 @@ public class DefaultEntityClassifier implements @Override public String getName() { - return "DefaultEntityClass"; + return name; + } + + public void setName(String name) { + this.name = name; } } @@ -61,7 +72,16 @@ public class DefaultEntityClassifier implements static { keyFields = EnumSet.of(DeviceField.MAC, DeviceField.VLAN); } - protected static IEntityClass entityClass = new DefaultEntityClass(); + protected static DefaultEntityClass entityClass = + new DefaultEntityClass("DefaultEntityClass"); + + public void setClassifierName (String name) { + entityClass.setName(name); + } + + public String getClassifierName (String name) { + return entityClass.getName(); + } @Override public IEntityClass classifyEntity(Entity entity) { @@ -121,4 +141,10 @@ public class DefaultEntityClassifier implements public void startUp(FloodlightModuleContext context) { // no-op } + + @Override + public void addListener(IEntityClassListener listener) { + // no-op + + } } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index 7246663a8318068064d0f180e4afb31faad91581..d5d53e5a9e502a46227a8c08462673cb0b92dfd5 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -49,6 +49,7 @@ import net.floodlightcontroller.core.util.SingletonTask; import net.floodlightcontroller.devicemanager.IDevice; import net.floodlightcontroller.devicemanager.IDeviceService; import net.floodlightcontroller.devicemanager.IEntityClass; +import net.floodlightcontroller.devicemanager.IEntityClassListener; import net.floodlightcontroller.devicemanager.IEntityClassifierService; import net.floodlightcontroller.devicemanager.IDeviceListener; import net.floodlightcontroller.devicemanager.SwitchPort; @@ -86,7 +87,7 @@ import org.slf4j.LoggerFactory; */ public class DeviceManagerImpl implements IDeviceService, IOFMessageListener, -IStorageSourceListener, IFloodlightModule, +IStorageSourceListener, IFloodlightModule, IEntityClassListener, IFlowReconcileListener, IInfoProvider, IHAListener { protected static Logger logger = LoggerFactory.getLogger(DeviceManagerImpl.class); @@ -461,12 +462,6 @@ IFlowReconcileListener, IInfoProvider, IHAListener { deviceListeners.add(listener); } - @Override - public void flushEntityCache(IEntityClass entityClass, - boolean reclassify) { - // TODO Auto-generated method stub - } - // ************* // IInfoProvider // ************* @@ -639,11 +634,12 @@ IFlowReconcileListener, IInfoProvider, IHAListener { floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); floodlightProvider.addHAListener(this); flowReconcileMgr.addFlowReconcileListener(this); + entityClassifier.addListener(this); Runnable ecr = new Runnable() { @Override public void run() { - cleanupEntities(); + cleanupEntities(null, false); entityCleanupTask.reschedule(ENTITY_CLEANUP_INTERVAL, TimeUnit.SECONDS); } @@ -1286,10 +1282,46 @@ IFlowReconcileListener, IInfoProvider, IHAListener { } } + /** + * Flush and/or reclassify all entities in a class + * + * @param entityClass the class to flush. If null, flush all classes + * @param reclassify if true, begin an asynchronous task to reclassify the + * flushed entities + */ + private void flushEntityCache (Set<String> entityClassChangedSet, + boolean reclassify) { + if (reclassify) return; // TODO + + /* + * TODO This can be running at the same time by timer thread. Check + * and make sure that this is thread safe. + */ + cleanupEntities(entityClassChangedSet, true); + } + + // ********************* + // IEntityClassListener + // ********************* + @Override + public void entityClassChanged (Set<String> entityClassNames) { + + /* + * Flush the entire device entity cache for now. + */ + flushEntityCache(entityClassNames, false); + return; + } + /** * Clean up expired entities/devices + * + * @param[in] forceCleanup ForceCleanup of entities irrespective of age + * @param[in] specificEntities Cleanup only a specific set of entities */ - protected void cleanupEntities() { + protected void cleanupEntities (Set<String> specificEntities, + boolean forceCleanup) { + Calendar c = Calendar.getInstance(); c.add(Calendar.MILLISECOND, -ENTITY_TIMEOUT); Date cutoff = c.getTime(); @@ -1304,13 +1336,23 @@ IFlowReconcileListener, IInfoProvider, IHAListener { while (diter.hasNext()) { Device d = diter.next(); + /* + * If we are cleaning entities for a specific set of devices, + * skip if not applicable. + */ + if (specificEntities != null && d.getEntityClass() != null && + !specificEntities.contains(d.getEntityClass().getName())) { + continue; + } + while (true) { deviceUpdates.clear(); toRemove.clear(); toKeep.clear(); for (Entity e : d.getEntities()) { - if (e.getLastSeenTimestamp() != null && - 0 > e.getLastSeenTimestamp().compareTo(cutoff)) { + if (forceCleanup || + (e.getLastSeenTimestamp() != null && + 0 > e.getLastSeenTimestamp().compareTo(cutoff))) { // individual entity needs to be removed toRemove.add(e); } else {