package net.floodlightcontroller.core.module; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Properties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; /** * Load an application from a configuration directory * @author readams */ public class ApplicationLoader implements IFloodlightModule, IApplicationService { /** * Representation for the application configuration * @author readams */ public static class Application { private String name; private String[] modules; private Map<String,String> config; public String getName() { return name; } public void setName(String name) { this.name = name; } public String[] getModules() { return modules; } public void setModules(String[] modules) { this.modules = modules; } public Map<String, String> getConfig() { return config; } public void setConfig(Map<String, String> config) { this.config = config; } } protected static Logger logger = LoggerFactory.getLogger(ApplicationLoader.class); protected static ObjectMapper mapper = new ObjectMapper(); protected static ObjectReader reader = mapper.reader(Application.class); IModuleService moduleService; private static String APP_RESOURCE_PATH = "apps/"; /** * Path containing application description files */ protected String applicationPath; /** * Application to load */ protected String application; // ***************** // IFloodlightModule // ***************** @Override public Collection<Class<? extends IFloodlightService>> getModuleServices() { Collection<Class<? extends IFloodlightService>> l = new ArrayList<Class<? extends IFloodlightService>>(); l.add(IApplicationService.class); return l; } @Override public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() { Map<Class<? extends IFloodlightService>, IFloodlightService> m = new HashMap<Class<? extends IFloodlightService>, IFloodlightService>(); // We are the class that implements the service m.put(IApplicationService.class, this); return m; } @Override public Collection<Class<? extends IFloodlightService>> getModuleDependencies() { return null; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { moduleService = context.getServiceImpl(IModuleService.class); Map<String,String> config = context.getConfigParams(this); if (config.containsKey("appsd")) applicationPath = config.get("appsd"); if (config.containsKey("application")) application = config.get("application"); } @Override public void startUp(FloodlightModuleContext context) throws FloodlightModuleException { if (application == null) { throw new FloodlightModuleException("No application to load"); } // attempt to load from application path File appPath; if (applicationPath != null && (appPath = new File(applicationPath)).exists() && appPath.isDirectory()) { File[] files = appPath.listFiles(); Arrays.sort(files); for (File f : files) { if (f.isFile() && f.getName().matches(".*\\.json$")); try { if (loadApplication(new FileInputStream(f), f.getPath())) return; } catch (FileNotFoundException e) { throw new FloodlightModuleException(e); } } } // attempt to load from classpath. Note here that the file needs // to be named after the application to be successful try { String r = APP_RESOURCE_PATH + application + ".json"; InputStream is = getClass().getClassLoader().getResourceAsStream(r); loadApplication(is, "resource: " + r); } catch (Exception e) { throw new FloodlightModuleException(e); } } private boolean loadApplication(InputStream is, String path) throws FloodlightModuleException { Application a; try { a = reader.readValue(is); } catch (Exception e) { throw new FloodlightModuleException("Could not read application " + path, e); } if (application.equals(a.getName())) { Properties p = new Properties(); if (a.getConfig() != null) p.putAll(a.getConfig()); if (a.getModules() != null) { logger.info("Loading application {}", a.getName()); moduleService.loadModulesFromList(Arrays.asList(a.getModules()), p); return true; } } return false; } }