package net.floodlightcontroller.core.module;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.floodlightcontroller.core.module.FloodlightModuleLoader;
import net.floodlightcontroller.core.module.IFloodlightModule;
import net.floodlightcontroller.core.test.MockFloodlightProvider;
import net.floodlightcontroller.core.test.MockThreadPoolService;
import net.floodlightcontroller.counter.NullCounterStore;
import net.floodlightcontroller.devicemanager.internal.DefaultEntityClassifier;
import net.floodlightcontroller.devicemanager.test.MockDeviceManager;
import net.floodlightcontroller.perfmon.NullPktInProcessingTime;
import net.floodlightcontroller.storage.memory.MemoryStorageSource;
import net.floodlightcontroller.topology.TopologyManager;
public class FloodlightTestModuleLoader extends FloodlightModuleLoader {
protected static Logger log = LoggerFactory.getLogger(FloodlightTestModuleLoader.class);
// List of default modules to use unless specified otherwise
public static final Class<? extends IFloodlightModule> DEFAULT_STORAGE_SOURCE =
MemoryStorageSource.class;
public static final Class<? extends IFloodlightModule> DEFAULT_FLOODLIGHT_PRPOVIDER =
MockFloodlightProvider.class;
public static final Class<? extends IFloodlightModule> DEFAULT_TOPOLOGY_PROVIDER =
TopologyManager.class;
public static final Class<? extends IFloodlightModule> DEFAULT_DEVICE_SERVICE =
MockDeviceManager.class;
public static final Class<? extends IFloodlightModule> DEFAULT_COUNTER_STORE =
NullCounterStore.class;
public static final Class<? extends IFloodlightModule> DEFAULT_THREADPOOL =
MockThreadPoolService.class;
public static final Class<? extends IFloodlightModule> DEFAULT_ENTITY_CLASSIFIER =
DefaultEntityClassifier.class;
public static final Class<? extends IFloodlightModule> DEFAULT_PERFMON =
NullPktInProcessingTime.class;
protected static final Collection<Class<? extends IFloodlightModule>> DEFAULT_MODULE_LIST;
static {
DEFAULT_MODULE_LIST = new ArrayList<Class<? extends IFloodlightModule>>();
DEFAULT_MODULE_LIST.add(DEFAULT_DEVICE_SERVICE);
DEFAULT_MODULE_LIST.add(DEFAULT_FLOODLIGHT_PRPOVIDER);
DEFAULT_MODULE_LIST.add(DEFAULT_STORAGE_SOURCE);
DEFAULT_MODULE_LIST.add(DEFAULT_TOPOLOGY_PROVIDER);
DEFAULT_MODULE_LIST.add(DEFAULT_COUNTER_STORE);
DEFAULT_MODULE_LIST.add(DEFAULT_THREADPOOL);
DEFAULT_MODULE_LIST.add(DEFAULT_ENTITY_CLASSIFIER);
DEFAULT_MODULE_LIST.add(DEFAULT_PERFMON);
}
protected IFloodlightModuleContext fmc;
/**
* Adds default modules to the list of modules to load. This is done
* in order to avoid the module loader throwing errors about duplicate
* modules and neither one is specified by the user.
* @param userModules The list of user specified modules to add to.
*/
protected void addDefaultModules(Collection<Class<? extends IFloodlightModule>> userModules) {
Collection<Class<? extends IFloodlightModule>> defaultModules =
new ArrayList<Class<? extends IFloodlightModule>>(DEFAULT_MODULE_LIST.size());
defaultModules.addAll(DEFAULT_MODULE_LIST);
Iterator<Class<? extends IFloodlightModule>> modIter = userModules.iterator();
while (modIter.hasNext()) {
Class<? extends IFloodlightModule> userMod = modIter.next();
Iterator<Class<? extends IFloodlightModule>> dmIter = defaultModules.iterator();
while (dmIter.hasNext()) {
Class<? extends IFloodlightModule> dmMod = dmIter.next();
Collection<Class<? extends IFloodlightService>> userModServs;
Collection<Class<? extends IFloodlightService>> dmModServs;
try {
dmModServs = dmMod.newInstance().getModuleServices();
userModServs = userMod.newInstance().getModuleServices();
} catch (InstantiationException e) {
log.error(e.getMessage());
break;
} catch (IllegalAccessException e) {
log.error(e.getMessage());
break;
}
// If either of these are null continue as they have no services
if (dmModServs == null || userModServs == null) continue;
// If the user supplied modules has a service
// that is in the default module list we remove
// the default module from the list.
boolean shouldBreak = false;
Iterator<Class<? extends IFloodlightService>> userModServsIter
= userModServs.iterator();
while (userModServsIter.hasNext()) {
Class<? extends IFloodlightService> userModServIntf = userModServsIter.next();
Iterator<Class<? extends IFloodlightService>> dmModsServsIter
= dmModServs.iterator();
while (dmModsServsIter.hasNext()) {
Class<? extends IFloodlightService> dmModServIntf
= dmModsServsIter.next();
if (dmModServIntf.getCanonicalName().equals(
userModServIntf.getCanonicalName())) {
logger.debug("Removing default module {} because it was " +
"overriden by an explicitly specified module",
dmModServIntf.getCanonicalName());
dmIter.remove();
shouldBreak = true;
break;
}
}
if (shouldBreak) break;
}
if (shouldBreak) break;
}
}
// Append the remaining default modules to the user specified ones.
// This avoids the module loader throwing duplicate module errors.
userModules.addAll(defaultModules);
log.debug("Using module set " + userModules.toString());
}
/**
* Sets up all modules and their dependencies.
* @param modules The list of modules that the user wants to load.
* @param mockedServices The list of services that will be mocked. Any
* module that provides this service will not be loaded.
*/
public void setupModules(Collection<Class<? extends IFloodlightModule>> modules,
Collection<IFloodlightService> mockedServices) {
addDefaultModules(modules);
Collection<String> modulesAsString = new ArrayList<String>();
for (Class<? extends IFloodlightModule> m : modules) {
modulesAsString.add(m.getCanonicalName());
}
try {
fmc = loadModulesFromList(modulesAsString, null, mockedServices);
} catch (FloodlightModuleException e) {
log.error(e.getMessage());
}
}
/**
* Gets the inited/started instance of a module from the context.
* @param ifl The name if the module to get, i.e. "LearningSwitch.class".
* @return The inited/started instance of the module.
*/
public IFloodlightModule getModuleByName(Class<? extends IFloodlightModule> ifl) {
Collection<IFloodlightModule> modules = fmc.getAllModules();
for (IFloodlightModule m : modules) {
if (ifl.getCanonicalName().equals(m.getClass().getCanonicalName())) {
return m;
}
}
return null;
}
/**
* Gets an inited/started instance of a service from the context.
* @param ifs The name of the service to get, i.e. "ITopologyService.class".
* @return The inited/started instance of the service from teh context.
*/
public IFloodlightService getModuleByService(Class<? extends IFloodlightService> ifs) {
Collection<IFloodlightModule> modules = fmc.getAllModules();
for (IFloodlightModule m : modules) {
Collection<Class<? extends IFloodlightService>> mServs = m.getModuleServices();
if (mServs == null) continue;
for (Class<? extends IFloodlightService> mServClass : mServs) {
if (mServClass.getCanonicalName().equals(ifs.getCanonicalName())) {
assert(m instanceof IFloodlightService);
return (IFloodlightService)m;
}
}
}
return null;
}
}