From 8393667f500ba486673ccd7885559d00283ab393 Mon Sep 17 00:00:00 2001 From: Alex Reimers <alex@bigswitch.com> Date: Fri, 27 Jan 2012 16:18:39 -0800 Subject: [PATCH] Finished module loading system (execpt for all the things that don't work yet). --- ...htcontroller.core.module.IFloodlightModule | 7 + .../floodlightcontroller/core/CoreModule.java | 44 ++- ...r.java => IFloodlightProviderService.java} | 7 +- .../core/IOFMessageFilterManagerService.java | 10 + .../net/floodlightcontroller/core/Main.java | 7 +- .../core/OFMessageFilterManager.java | 114 ++++--- .../core/internal/Controller.java | 287 ++++++----------- .../core/internal/OFMessageFuture.java | 8 +- .../core/internal/OFStatisticsFuture.java | 6 +- .../core/internal/OFSwitchImpl.java | 6 +- .../TerminationStorageExceptionHandler.java | 6 +- .../core/module/FloodlightModuleContext.java | 50 +-- .../core/module/FloodlightModuleLoader.java | 218 ++++++++----- .../core/module/IFloodlightModule.java | 23 +- .../core/module/IFloodlightModuleContext.java | 15 +- .../core/web/AllSwitchStatisticsResource.java | 6 +- .../core/web/ControllerSwitchesResource.java | 4 +- .../core/web/CounterResource.java | 10 +- .../core/web/CounterResourceBase.java | 6 +- .../core/web/SwitchClustersResource.java | 4 +- .../web/SwitchCounterCategoriesResource.java | 8 +- .../core/web/SwitchCounterResource.java | 12 +- .../core/web/SwitchResourceBase.java | 6 +- .../core/web/SwitchStatisticsResource.java | 4 +- .../counter/ConcurrentCounter.java | 4 +- .../counter/CountBuffer.java | 2 +- .../counter/CountSeries.java | 2 +- .../counter/CounterStore.java | 50 +-- .../{ICounterService.java => ICounter.java} | 4 +- .../counter/ICounterStoreService.java | 43 +++ .../counter/SimpleCounter.java | 4 +- .../devicemanager/IDeviceManagerService.java | 6 + .../internal/DeviceManagerImpl.java | 167 ++++++---- .../forwarding/Forwarding.java | 67 +++- .../net/floodlightcontroller/hub/Hub.java | 6 +- .../learningswitch/LearningSwitch.java | 17 +- .../routing/ForwardingBase.java | 30 +- ...Engine.java => IRoutingEngineService.java} | 3 +- .../routing/dijkstra/RoutingImpl.java | 88 ++++-- .../IStaticFlowEntryPusherService.java | 3 +- .../StaticFlowEntryPusher.java | 107 ++++--- .../storage/AbstractStorageSource.java | 18 +- .../storage/memory/MemoryStorageSource.java | 47 ++- .../storage/nosql/NoSqlStorageSource.java | 7 - .../topology/ITopologyService.java | 7 +- .../topology/internal/TopologyImpl.java | 292 +++++++++--------- .../core/internal/ControllerTest.java | 4 +- .../core/test/MockFloodlightProvider.java | 8 +- .../internal/DeviceManagerImplTest.java | 2 +- .../forwarding/ForwardingTest.java | 10 +- .../StaticFlowEntryPusherTest.java | 4 +- .../test/FloodlightTestCase.java | 6 +- 52 files changed, 1095 insertions(+), 781 deletions(-) rename src/main/java/net/floodlightcontroller/core/{IFloodlightProvider.java => IFloodlightProviderService.java} (96%) create mode 100644 src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java rename src/main/java/net/floodlightcontroller/counter/{ICounterService.java => ICounter.java} (93%) create mode 100644 src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java rename src/main/java/net/floodlightcontroller/routing/{IRoutingEngine.java => IRoutingEngineService.java} (94%) diff --git a/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule b/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule index adb57d6b7..9d4a19046 100644 --- a/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule +++ b/src/main/java/META-INF/services/net.floodlightcontroller.core.module.IFloodlightModule @@ -1 +1,8 @@ net.floodlightcontroller.core.CoreModule +net.floodlightcontroller.storage.memory.MemoryStorageSource +net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl +net.floodlightcontroller.topology.internal.TopologyImpl +net.floodlightcontroller.routing.dijkstra.RoutingImpl +net.floodlightcontroller.forwarding.Forwarding +net.floodlightcontroller.core.OFMessageFilterManager +net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher \ No newline at end of file diff --git a/src/main/java/net/floodlightcontroller/core/CoreModule.java b/src/main/java/net/floodlightcontroller/core/CoreModule.java index 67a9680b9..0dc6d9de1 100644 --- a/src/main/java/net/floodlightcontroller/core/CoreModule.java +++ b/src/main/java/net/floodlightcontroller/core/CoreModule.java @@ -2,48 +2,64 @@ package net.floodlightcontroller.core; import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; +import java.util.Map; import net.floodlightcontroller.core.internal.Controller; import net.floodlightcontroller.core.module.FloodlightModuleContext; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.IFloodlightModule; +import net.floodlightcontroller.counter.CounterStore; +import net.floodlightcontroller.counter.ICounterStoreService; +import net.floodlightcontroller.storage.IStorageSourceService; public class CoreModule implements IFloodlightModule { - protected static Collection<Class<? extends IFloodlightService>> services; Controller controller; - static { - services = new ArrayList<Class<? extends IFloodlightService>>(1); - services.add(IFloodlightProvider.class); - } - @Override public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> services = + new ArrayList<Class<? extends IFloodlightService>>(2); + services.add(IFloodlightProviderService.class); + services.add(ICounterStoreService.class); return services; } @Override - public Collection<IFloodlightService> getServiceImpls() { - Collection<IFloodlightService> l = new ArrayList<IFloodlightService>(1); + public Map<Class<? extends IFloodlightService>, + IFloodlightService> getServiceImpls() { controller = new Controller(); - l.add(controller); - return l; + ICounterStoreService counterStore = new CounterStore(); + controller.setCounterStore(counterStore); + + Map<Class<? extends IFloodlightService>, + IFloodlightService> m = + new HashMap<Class<? extends IFloodlightService>, + IFloodlightService>(); + m.put(IFloodlightProviderService.class, controller); + m.put(ICounterStoreService.class, counterStore); + return m; } @Override - public Collection<? extends IFloodlightService> getDependencies() { - return null; + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> dependencies = + new ArrayList<Class<? extends IFloodlightService>>(1); + dependencies.add(IStorageSourceService.class); + return dependencies; } @Override public void init(FloodlightModuleContext context) throws FloodlightModuleException { + IStorageSourceService storage = + (IStorageSourceService) + context.getServiceImpl(IStorageSourceService.class); + controller.setStorageSourceService(storage); controller.init(); } @Override public void startUp(FloodlightModuleContext context) { controller.startupComponents(); - controller.run(); } - } diff --git a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java similarity index 96% rename from src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java rename to src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java index a9547e84f..5980ba9f1 100644 --- a/src/main/java/net/floodlightcontroller/core/IFloodlightProvider.java +++ b/src/main/java/net/floodlightcontroller/core/IFloodlightProviderService.java @@ -33,7 +33,7 @@ import org.openflow.protocol.factory.BasicFactory; * * @author David Erickson (daviderickson@cs.stanford.edu) */ -public interface IFloodlightProvider extends IFloodlightService { +public interface IFloodlightProviderService extends IFloodlightService { /** * A value stored in the floodlight context containing a parsed packet @@ -133,4 +133,9 @@ public interface IFloodlightProvider extends IFloodlightService { * @return an OpenFlow message factory */ public BasicFactory getOFMessageFactory(); + + /** + * Run the main I/O loop of the Controller. + */ + public void run(); } diff --git a/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java new file mode 100644 index 000000000..df77cdf45 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/core/IOFMessageFilterManagerService.java @@ -0,0 +1,10 @@ +package net.floodlightcontroller.core; + +import org.openflow.protocol.OFMessage; + +public interface IOFMessageFilterManagerService extends IFloodlightService { + + public String getDataAsString(IOFSwitch sw, OFMessage msg, + FloodlightContext cntx); + +} diff --git a/src/main/java/net/floodlightcontroller/core/Main.java b/src/main/java/net/floodlightcontroller/core/Main.java index f217118b3..d681f8ee9 100644 --- a/src/main/java/net/floodlightcontroller/core/Main.java +++ b/src/main/java/net/floodlightcontroller/core/Main.java @@ -2,6 +2,7 @@ package net.floodlightcontroller.core; import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.core.module.FloodlightModuleLoader; +import net.floodlightcontroller.core.module.IFloodlightModuleContext; /** * Host for the Floodlight main method @@ -19,7 +20,9 @@ public class Main { "org.restlet.ext.slf4j.Slf4jLoggerFacade"); FloodlightModuleLoader fml = new FloodlightModuleLoader(); - fml.loadModulesFromConfig(); + IFloodlightModuleContext moduleContext = fml.loadModulesFromConfig(); + IFloodlightProviderService controller = + moduleContext.getServiceImpl(IFloodlightProviderService.class); + controller.run(); } - } diff --git a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java index b096f79cc..4cde652ce 100644 --- a/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java +++ b/src/main/java/net/floodlightcontroller/core/OFMessageFilterManager.java @@ -19,7 +19,9 @@ package net.floodlightcontroller.core; import java.text.DateFormat; import java.text.SimpleDateFormat; +import java.util.Collection; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.Map; @@ -49,10 +51,14 @@ import org.apache.thrift.transport.TTransportException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packetstreamer.thrift.*; -public class OFMessageFilterManager implements IOFMessageListener { +public class OFMessageFilterManager + implements IOFMessageListener, IFloodlightModule, IOFMessageFilterManagerService { /** * @author Srini @@ -65,7 +71,7 @@ public class OFMessageFilterManager implements IOFMessageListener { protected static TTransport transport = null; protected static PacketStreamer.Client packetClient = null; - protected IFloodlightProvider floodlightProvider = null; + protected IFloodlightProviderService floodlightProvider = null; // filter List is a key value pair. Key is the session id, value is the filter rules. protected ConcurrentHashMap<String, ConcurrentHashMap<String,String>> filterMap = null; protected ConcurrentHashMap<String, Long> filterTimeoutMap = null; @@ -91,13 +97,6 @@ public class OFMessageFilterManager implements IOFMessageListener { FILTER_NOT_DEFINED, FILTER_NO_MATCH, FILTER_MATCH } - public void init (IFloodlightProvider bp) { - floodlightProvider = bp; - filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>(); - filterTimeoutMap = new ConcurrentHashMap<String, Long>(); - serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090")); - } - protected String addFilter(ConcurrentHashMap<String,String> f, long delta) { // Create unique session ID. @@ -200,8 +199,8 @@ public class OFMessageFilterManager implements IOFMessageListener { Ethernet eth = null; if (m.getType() == OFType.PACKET_IN) { - eth = IFloodlightProvider.bcStore.get(cntx, - IFloodlightProvider.CONTEXT_PI_PAYLOAD); + eth = IFloodlightProviderService.bcStore.get(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD); } else if (m.getType() == OFType.PACKET_OUT) { eth = new Ethernet(); OFPacketOut p = (OFPacketOut) m; @@ -254,30 +253,7 @@ public class OFMessageFilterManager implements IOFMessageListener { else return matchedFilters; } - - - protected void startListening() { - floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); - floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this); - floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this); - } - - protected void stopListening() { - floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this); - floodlightProvider.removeOFMessageListener(OFType.PACKET_OUT, this); - floodlightProvider.removeOFMessageListener(OFType.FLOW_MOD, this); - } - - public void startUp() { - startListening(); - //connectToPSServer(); - } - - public void shutDown() { - stopListening(); - disconnectFromPSServer(); - } - + public boolean connectToPSServer() { int numRetries = 0; if (transport != null && transport.isOpen()) { @@ -464,6 +440,7 @@ public class OFMessageFilterManager implements IOFMessageListener { } } + @Override public String getDataAsString(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) { Ethernet eth; @@ -495,8 +472,8 @@ public class OFMessageFilterManager implements IOFMessageListener { // If the conext is not set by floodlight, then ignore. if (cntx != null) { // packet type icmp, arp, etc. - eth = IFloodlightProvider.bcStore.get(cntx, - IFloodlightProvider.CONTEXT_PI_PAYLOAD); + eth = IFloodlightProviderService.bcStore.get(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD); if (eth != null) sb.append(eth.toString()); } @@ -526,8 +503,8 @@ public class OFMessageFilterManager implements IOFMessageListener { // If the conext is not set by floodlight, then ignore. if (cntx != null) { - eth = IFloodlightProvider.bcStore.get(cntx, - IFloodlightProvider.CONTEXT_PI_PAYLOAD); + eth = IFloodlightProviderService.bcStore.get(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD); if (eth != null) sb.append(eth.toString()); } @@ -561,4 +538,63 @@ public class OFMessageFilterManager implements IOFMessageListener { return this.getDataAsString(sw, msg, cntx).getBytes(); } + // IFloodlightModule methods + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IOFMessageFilterManagerService.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(IOFMessageFilterManagerService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IFloodlightProviderService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + if (log.isDebugEnabled()) { + log.debug("Init " + this.getClass().getCanonicalName()); + } + + + } + + @Override + public void startUp(FloodlightModuleContext context) { + // This is our 'constructor' + if (log.isDebugEnabled()) { + log.debug("Starting " + this.getClass().getCanonicalName()); + } + this.floodlightProvider = + context.getServiceImpl(IFloodlightProviderService.class); + if (this.floodlightProvider == null) { + System.out.println("FLOODLIGHTPROVDIER IS NUL!!!!!"); + } + filterMap = new ConcurrentHashMap<String, ConcurrentHashMap<String,String>>(); + filterTimeoutMap = new ConcurrentHashMap<String, Long>(); + serverPort = Integer.parseInt(System.getProperty("net.floodlightcontroller.packetstreamer.port", "9090")); + + floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); + floodlightProvider.addOFMessageListener(OFType.PACKET_OUT, this); + floodlightProvider.addOFMessageListener(OFType.FLOW_MOD, this); + } } diff --git a/src/main/java/net/floodlightcontroller/core/internal/Controller.java b/src/main/java/net/floodlightcontroller/core/internal/Controller.java index 7ce555637..dd8bea7e7 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/Controller.java +++ b/src/main/java/net/floodlightcontroller/core/internal/Controller.java @@ -25,7 +25,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -46,14 +45,13 @@ import java.util.concurrent.TimeoutException; import java.nio.channels.ClosedChannelException; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFController; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFMessageListener.Command; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchFilter; import net.floodlightcontroller.core.IOFSwitchListener; -import net.floodlightcontroller.core.OFMessageFilterManager; import net.floodlightcontroller.core.internal.OFChannelState.HandshakeState; import net.floodlightcontroller.core.util.ListenerDispatcher; import net.floodlightcontroller.core.web.CoreWebRoutable; @@ -61,26 +59,19 @@ import net.floodlightcontroller.core.web.JacksonCustomConverter; import net.floodlightcontroller.core.web.RestletRoutable; import static net.floodlightcontroller.counter.CounterValue.CounterType; import net.floodlightcontroller.counter.CounterStore; -import net.floodlightcontroller.counter.ICounterService; +import net.floodlightcontroller.counter.ICounter; import net.floodlightcontroller.counter.CounterStore.NetworkLayer; -import net.floodlightcontroller.devicemanager.IDeviceManagerAware; -import net.floodlightcontroller.devicemanager.internal.DeviceManagerImpl; -import net.floodlightcontroller.forwarding.Forwarding; +import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.jython.Server; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.IPv4; -import net.floodlightcontroller.routing.dijkstra.RoutingImpl; -import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher; import net.floodlightcontroller.perfmon.PktinProcessingTime; import net.floodlightcontroller.storage.IResultSet; import net.floodlightcontroller.storage.IStorageExceptionHandler; import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.OperatorPredicate; import net.floodlightcontroller.storage.StorageException; -import net.floodlightcontroller.storage.memory.MemoryStorageSource; import net.floodlightcontroller.storage.web.StorageWebRoutable; -import net.floodlightcontroller.topology.ITopologyListener; -import net.floodlightcontroller.topology.internal.TopologyImpl; import net.floodlightcontroller.topology.web.TopologyWebRouteable; import org.jboss.netty.bootstrap.ServerBootstrap; @@ -100,8 +91,6 @@ import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory; import org.jboss.netty.handler.timeout.IdleStateAwareChannelUpstreamHandler; import org.jboss.netty.handler.timeout.IdleStateEvent; import org.jboss.netty.handler.timeout.ReadTimeoutException; -import org.kohsuke.args4j.CmdLineException; -import org.kohsuke.args4j.CmdLineParser; import org.openflow.protocol.OFEchoReply; import org.openflow.protocol.OFError; import org.openflow.protocol.OFError.OFBadActionCode; @@ -150,7 +139,7 @@ import org.slf4j.LoggerFactory; */ public class Controller extends Application - implements IFloodlightProvider, IOFController { + implements IFloodlightProviderService, IOFController { protected static Logger log = LoggerFactory.getLogger(Controller.class); @@ -161,19 +150,14 @@ public class Controller protected ConcurrentHashMap<Long, IOFSwitch> switches; protected Set<IOFSwitchListener> switchListeners; protected BlockingQueue<Update> updates; - protected CounterStore counterStore; + protected ICounterStoreService counterStore; protected ScheduledExecutorService executor = Executors.newScheduledThreadPool(5); protected IStorageSourceService storageSource; - protected TopologyImpl topology; - protected DeviceManagerImpl deviceManager; - protected RoutingImpl routingEngine; - protected Forwarding forwarding; - protected OFMessageFilterManager messageFilterManager; + //protected IOFMessageFilterManagerService messageFilterManager; protected PktinProcessingTime pktinProcTime; - private StaticFlowEntryPusher staticFlowEntryPusher; protected long ptWarningThresholdInNano; protected List<RestletRoutable> restlets; @@ -240,6 +224,18 @@ public class Controller this.moduleFile = settings.getModuleFile(); } + // *************** + // Getters/Setters + // *************** + + public void setStorageSourceService(IStorageSourceService storageSource) { + this.storageSource = storageSource; + } + + public void setCounterStore(ICounterStoreService counterStore) { + this.counterStore = counterStore; + } + // ********************** // ChannelUpstreamHandler // ********************** @@ -657,28 +653,28 @@ public class Controller NetworkLayer.L3); try { - ICounterService portCounter = + ICounter portCounter = counterStore.getCounter(portCounterName); if (portCounter == null) { portCounter = counterStore.createCounter(portCounterName, CounterType.LONG); } - ICounterService switchCounter = + ICounter switchCounter = counterStore.getCounter(switchCounterName); if (switchCounter == null) { switchCounter = counterStore.createCounter(switchCounterName, CounterType.LONG); } - ICounterService portL3Counter = + ICounter portL3Counter = counterStore.getCounter(portL3CategoryCounterName); if (portL3Counter == null) { portL3Counter = counterStore.createCounter(portL3CategoryCounterName, CounterType.LONG); } - ICounterService switchL3Counter = + ICounter switchL3Counter = counterStore.getCounter(switchL3CategoryCounterName); if (switchL3Counter == null) { switchL3Counter = @@ -690,7 +686,7 @@ public class Controller portL3Counter.increment(); switchL3Counter.increment(); - if (etherType.compareTo(CounterStore.L3ET_IPV4) == 0) { + if (etherType.compareTo(ICounterStoreService.L3ET_IPV4) == 0) { IPv4 ipV4 = (IPv4)eth.getPayload(); String l4Type = String.format("%02x", ipV4.getProtocol()); if (TypeAliases.l4TypeAliasMap != null && @@ -712,14 +708,14 @@ public class Controller l4Type, NetworkLayer.L4); - ICounterService portL4Counter = + ICounter portL4Counter = counterStore.getCounter(portL4CategoryCounterName); if (portL4Counter == null) { portL4Counter = counterStore.createCounter(portL4CategoryCounterName, CounterType.LONG); } - ICounterService switchL4Counter = + ICounter switchL4Counter = counterStore.getCounter(switchL4CategoryCounterName); if (switchL4Counter == null) { switchL4Counter = @@ -780,8 +776,8 @@ public class Controller bc = bContext; } if (eth != null) { - IFloodlightProvider.bcStore.put(bc, - IFloodlightProvider.CONTEXT_PI_PAYLOAD, + IFloodlightProviderService.bcStore.put(bc, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } @@ -789,10 +785,10 @@ public class Controller // The context would have the necessary information for // the OFMessageFilterManager's getDataToString to work // for packet-ins. - if (log.isDebugEnabled()) { - String str = messageFilterManager.getDataAsString(sw, m, bc); - log.trace("{}", str); - } + //if (log.isDebugEnabled()) { + // String str = messageFilterManager.getDataAsString(sw, m, bc); + // log.trace("{}", str); + //} // Get the starting time (overall and per-component) of @@ -828,8 +824,8 @@ public class Controller long processingTime = System.nanoTime() - startTime; if (ptWarningThresholdInNano > 0 && processingTime > ptWarningThresholdInNano) { log.warn("Time to process packet-in: {} us", processingTime/1000.0); - if (eth != null) - log.warn("{}", messageFilterManager.getDataAsString(sw, m, bContext)); + //if (eth != null) + // log.warn("{}", messageFilterManager.getDataAsString(sw, m, bContext)); } } } @@ -1059,10 +1055,10 @@ public class Controller @Override public void handleOutgoingMessage(IOFSwitch sw, OFMessage m, FloodlightContext bc) { - if (log.isDebugEnabled()) { - String str = messageFilterManager.getDataAsString(sw, m, bc); - log.trace("{}", str); - } + //if (log.isDebugEnabled()) { + // String str = messageFilterManager.getDataAsString(sw, m, bc); + // log.trace("{}", str); + //} List<IOFMessageListener> listeners = null; if (messageListeners.containsKey(m.getType())) { @@ -1135,58 +1131,6 @@ public class Controller // ************** // Initialization // ************** - /** - * Call after init() has run, but before this.run() - * @throws IOException - */ - - protected void startUp() throws IOException { - // Connect to the storage source to update info about this controller - // node, and wait indefinitely if the storage source is unavailable; - // don't want switches to connect before we have a database - while (true) { - try { - updateControllerInfo(); - break; - } - catch (StorageException e) { - log.info("Waiting for storage source"); - try { - Thread.sleep(1000); - } catch (InterruptedException e1) { - } - } - } - log.info("Connected to storage source"); - - switches = new ConcurrentHashMap<Long, IOFSwitch>(); - - this.factory = new BasicFactory(); - } - - protected void shutDown() { - try { - removeControllerInfo(); - } catch (StorageException e) { - } - - log.info("Shutdown complete"); - } - - protected void setStorageSource(IStorageSourceService storageSource) { - this.storageSource = storageSource; - IStorageExceptionHandler handler = - new TerminationStorageExceptionHandler(this); - storageSource.setExceptionHandler(handler); - storageSource.createTable(CONTROLLER_TABLE_NAME, null); - storageSource.createTable(SWITCH_TABLE_NAME, null); - storageSource.createTable(PORT_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME, - CONTROLLER_ID); - storageSource.setTablePrimaryKeyName(SWITCH_TABLE_NAME, - SWITCH_DATAPATH_ID); - storageSource.setTablePrimaryKeyName(PORT_TABLE_NAME, PORT_ID); - } protected void updateAllInactiveSwitchInfo() { String controllerId = getControllerId(); @@ -1252,17 +1196,6 @@ public class Controller storageSource.updateRow(CONTROLLER_TABLE_NAME, controllerInfo); } - protected void removeControllerInfo() { - // Update the controller info in the storage source to be inactive -// Map<String, Object> controllerInfo = new HashMap<String, Object>(); -// String id = getControllerId(); -// controllerInfo.put(CONTROLLER_ID, id); -// controllerInfo.put(CONTROLLER_ACTIVE, Boolean.FALSE); -// storageSource.updateRow(CONTROLLER_TABLE_NAME, controllerInfo); - - updateAllInactiveSwitchInfo(); - } - protected void updateActiveSwitchInfo(IOFSwitch sw) { // Obtain the row info for the switch Map<String, Object> switchInfo = new HashMap<String, Object>(); @@ -1430,78 +1363,20 @@ public class Controller * new components */ public void init() { - topology = new TopologyImpl(); - deviceManager = new DeviceManagerImpl(); counterStore = new CounterStore(); pktinProcTime = new PktinProcessingTime(); - routingEngine = new RoutingImpl(); - initStorageSource(); - - topology.setFloodlightProvider(this); - topology.setStorageSource(storageSource); - - deviceManager.setFloodlightProvider(this); - deviceManager.setStorageSource(storageSource); - deviceManager.setTopology(topology); - - initMessageFilterManager(); - initStaticFlowPusher(); - initForwarding(); - - // call this explicitly because it does setup - this.setStorageSource(storageSource); - - HashSet<ITopologyListener> topologyAware = new HashSet<ITopologyListener>(); - topologyAware.add(deviceManager); - topologyAware.add(routingEngine); - topology.setTopologyAware(topologyAware); - topology.setRoutingEngine(routingEngine); - - HashSet<IDeviceManagerAware> dmAware = - new HashSet<IDeviceManagerAware>(); - dmAware.add(forwarding); - deviceManager.setDeviceManagerAware(dmAware); restlets.add(new CoreWebRoutable()); restlets.add(new StorageWebRoutable()); restlets.add(new TopologyWebRouteable()); - JacksonCustomConverter.replaceConverter(); - - // Processing Time Warning Threshold - ptWarningThresholdInNano = Long.parseLong(System.getProperty("net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000; - if (ptWarningThresholdInNano > 0) { - log.info("Packet processing time threshold for warning set to {} ms.", - ptWarningThresholdInNano/1000000); - } - } - - protected void initStorageSource() { - storageSource = new MemoryStorageSource(); - } - - protected void initMessageFilterManager() { - messageFilterManager = new OFMessageFilterManager(); - messageFilterManager.init(this); - } - - protected void initStaticFlowPusher() { - staticFlowEntryPusher = new StaticFlowEntryPusher(); - staticFlowEntryPusher.setFloodlightProvider(this); - } - - protected void initForwarding() { - forwarding = new Forwarding(); - forwarding.setFloodlightProvider(this); - forwarding.setCounterStore(counterStore); - forwarding.setDeviceManager(deviceManager); - forwarding.setRoutingEngine(routingEngine); - forwarding.setTopology(topology); + JacksonCustomConverter.replaceConverter(); } /** * Initialize the rest context */ protected void initRestContext(Context context) { + /* context.getAttributes().put("floodlightProvider", this); context.getAttributes().put("counterStore", counterStore); context.getAttributes().put("storageSource", storageSource); @@ -1514,35 +1389,55 @@ public class Controller staticFlowEntryPusher); } context.getAttributes().put("topology", topology); + */ } /** * Startup all of the controller's components */ public void startupComponents() { - // now, do our own init - try { - log.debug("Doing controller internal setup"); - this.startUp(); - } catch (IOException e) { - throw new RuntimeException(e); + log.debug("Doing controller internal setup"); + // Set floodlight to terminate on a storage exception + IStorageExceptionHandler handler = + new TerminationStorageExceptionHandler(this); + storageSource.setExceptionHandler(handler); + + // Create the table names we use + storageSource.createTable(CONTROLLER_TABLE_NAME, null); + storageSource.createTable(SWITCH_TABLE_NAME, null); + storageSource.createTable(PORT_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName(CONTROLLER_TABLE_NAME, + CONTROLLER_ID); + storageSource.setTablePrimaryKeyName(SWITCH_TABLE_NAME, + SWITCH_DATAPATH_ID); + storageSource.setTablePrimaryKeyName(PORT_TABLE_NAME, PORT_ID); + + while (true) { + try { + updateControllerInfo(); + break; + } + catch (StorageException e) { + log.info("Waiting for storage source"); + try { + Thread.sleep(1000); + } catch (InterruptedException e1) { + } + } + } + log.info("Connected to storage source"); + + switches = new ConcurrentHashMap<Long, IOFSwitch>(); + this.factory = new BasicFactory(); + + // Processing Time Warning Threshold + ptWarningThresholdInNano = Long.parseLong(System.getProperty( + "net.floodlightcontroller.core.PTWarningThresholdInMilli", "0")) * 1000000; + if (ptWarningThresholdInNano > 0) { + log.info("Packet processing time threshold for warning set to {} ms.", + ptWarningThresholdInNano/1000000); } - log.debug("Starting topology service"); - topology.startUp(); - log.debug("Starting deviceManager service"); - deviceManager.startUp(); - // no need to do storageSource.startUp() - log.debug("Starting counterStore service"); - counterStore.startUp(); - log.debug("Starting routingEngine service"); - routingEngine.startUp(); - log.debug("Starting forwarding service"); - forwarding.startUp(); - log.debug("Starting messageFilter service"); - messageFilterManager.startUp(); - log.debug("Starting staticFlowEntryPusher service"); - staticFlowEntryPusher.startUp(); log.debug("Starting DebugServer"); this.debugserver_start(); } @@ -1553,15 +1448,15 @@ public class Controller protected void debugserver_start() { Map<String, Object> locals = new HashMap<String, Object>(); locals.put("controller", this); - locals.put("deviceManager", this.deviceManager); - locals.put("topology", this.topology); - locals.put("routingEngine", this.routingEngine); - locals.put("forwarding", this.forwarding); - locals.put("staticFlowEntryPusher", this.staticFlowEntryPusher); + //locals.put("deviceManager", this.deviceManager); + //locals.put("topology", this.topology); + //locals.put("routingEngine", this.routingEngine); + //locals.put("forwarding", this.forwarding); + //locals.put("staticFlowEntryPusher", this.staticFlowEntryPusher); locals.put("counterStore", this.counterStore); locals.put("storageSource", this.storageSource); locals.put("switches", this.switches); - locals.put("messageFilterManager", this.messageFilterManager); + //locals.put("messageFilterManager", this.messageFilterManager); Server debug_server = new Server(6655, locals); debug_server.start(); @@ -1571,6 +1466,7 @@ public class Controller * Main function entry point; override init() for adding modules * @param args Command line arguments */ + /* public static void main(String args[]) throws Exception { System.setProperty("org.restlet.engine.loggerFacadeClass", "org.restlet.ext.slf4j.Slf4jLoggerFacade"); @@ -1584,9 +1480,10 @@ public class Controller System.exit(1); } - Controller controller = new Controller(settings); - controller.init(); - controller.startupComponents(); - controller.run(); + //Controller controller = new Controller(settings); + //controller.init(); + //controller.startupComponents(); + //controller.run(); } + */ } diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java index 443568280..9f8b30e14 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFMessageFuture.java @@ -26,7 +26,7 @@ import java.util.concurrent.TimeoutException; import org.openflow.protocol.OFMessage; import org.openflow.protocol.OFType; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchFilter; import net.floodlightcontroller.core.IOFSwitchListener; @@ -42,7 +42,7 @@ import net.floodlightcontroller.core.IOFSwitchListener; public abstract class OFMessageFuture<T,V> implements Future<V>, IOFSwitchFilter, IOFSwitchListener { - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; protected volatile boolean canceled; protected CountDownLatch latch; protected OFType responseType; @@ -51,12 +51,12 @@ public abstract class OFMessageFuture<T,V> implements Future<V>, protected Runnable timeoutTimer; protected int transactionId; - public OFMessageFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw, + public OFMessageFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw, OFType responseType, int transactionId) { this(floodlightProvider, sw, responseType, transactionId, 60, TimeUnit.SECONDS); } - public OFMessageFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw, + public OFMessageFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw, OFType responseType, int transactionId, long timeout, TimeUnit unit) { this.floodlightProvider = floodlightProvider; this.canceled = false; diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java index 6c9870c51..306d38eea 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFStatisticsFuture.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.TimeUnit; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import org.openflow.protocol.OFMessage; @@ -40,13 +40,13 @@ public class OFStatisticsFuture extends protected volatile boolean finished; - public OFStatisticsFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw, + public OFStatisticsFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw, int transactionId) { super(floodlightProvider, sw, OFType.STATS_REPLY, transactionId); init(); } - public OFStatisticsFuture(IFloodlightProvider floodlightProvider, IOFSwitch sw, + public OFStatisticsFuture(IFloodlightProviderService floodlightProvider, IOFSwitch sw, int transactionId, long timeout, TimeUnit unit) { super(floodlightProvider, sw, OFType.STATS_REPLY, transactionId, timeout, unit); init(); diff --git a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java index afdd7beb9..811699133 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java +++ b/src/main/java/net/floodlightcontroller/core/internal/OFSwitchImpl.java @@ -30,7 +30,7 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.types.MacVlanPair; import net.floodlightcontroller.util.TimedCache; @@ -62,7 +62,7 @@ public class OFSwitchImpl implements IOFSwitch { protected static Logger log = LoggerFactory.getLogger(OFSwitchImpl.class); protected ConcurrentMap<Object, Object> attributes; - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; protected Date connectedSince; protected OFFeaturesReply featuresReply; protected String stringId; @@ -273,7 +273,7 @@ public class OFSwitchImpl implements IOFSwitch { /** * @param floodlightProvider the floodlightProvider to set */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { + public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } diff --git a/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java b/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java index 111dc2917..9b27ae1db 100644 --- a/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java +++ b/src/main/java/net/floodlightcontroller/core/internal/TerminationStorageExceptionHandler.java @@ -20,15 +20,15 @@ package net.floodlightcontroller.core.internal; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.storage.IStorageExceptionHandler; public class TerminationStorageExceptionHandler implements IStorageExceptionHandler { protected static Logger log = LoggerFactory.getLogger(TerminationStorageExceptionHandler.class); - private IFloodlightProvider floodlightProvider; + private IFloodlightProviderService floodlightProvider; - TerminationStorageExceptionHandler(IFloodlightProvider floodlightProvider) { + TerminationStorageExceptionHandler(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java index 309a94bdf..4041cfdc1 100644 --- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java +++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleContext.java @@ -1,10 +1,7 @@ package net.floodlightcontroller.core.module; -import java.util.ArrayList; -import java.util.Collection; +import java.util.HashMap; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - import net.floodlightcontroller.core.IFloodlightService; /** @@ -13,51 +10,32 @@ import net.floodlightcontroller.core.IFloodlightService; */ public class FloodlightModuleContext implements IFloodlightModuleContext { protected Map<Class<? extends IFloodlightService>, IFloodlightService> serviceMap; - protected Collection<IFloodlightModule> modules; /** * Creates the ModuleContext for use with this IFloodlightProvider. * This will be used as a module registry for all IFloodlightModule(s). */ public FloodlightModuleContext() { - serviceMap = new ConcurrentHashMap<Class<? extends IFloodlightService>, IFloodlightService>(); - modules = new ArrayList<IFloodlightModule>(); + serviceMap = + new HashMap<Class<? extends IFloodlightService>, + IFloodlightService>(); } /** * Adds a IFloodlightModule for this Context. + * @param clazz the service class * @param module The IFloodlightModule to add to the registry - * @param name The fully qualified name for the module that describes - * the service it provides, i.e. "deviceManager.floodlight" - */ - public void addService(IFloodlightService service) { - Class<? extends IFloodlightService> serviceClass = service.getClass(); - serviceMap.put(serviceClass, service); - } - - /** - * Retrieves a casted version of a module from the registry. - * @param name The IFloodlightService object type - * @return The IFloodlightService - * @throws FloodlightModuleException If the module was not found or a ClassCastException was encountered. */ - public IFloodlightService getService(Class<? extends IFloodlightService> service) { - return serviceMap.get(service); + public void addService(Class<? extends IFloodlightService> clazz, + IFloodlightService service) { + serviceMap.put(clazz, service); } - /** - * Add a module to the list of initialized modules - * @param module - */ - public void addModule(IFloodlightModule module) { - modules.add(module); - } + @SuppressWarnings("unchecked") + @Override + public <T extends IFloodlightService> T getServiceImpl(Class<T> service) { + IFloodlightService s = serviceMap.get(service); + return (T)s; + } - /** - * Get the list of initialized modules. - * @return the list of modules that have been initialized - */ - public Collection<IFloodlightModule> getModules() { - return modules; - } } diff --git a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java index 3681ef26a..7e8ef4946 100644 --- a/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java +++ b/src/main/java/net/floodlightcontroller/core/module/FloodlightModuleLoader.java @@ -3,8 +3,11 @@ package net.floodlightcontroller.core.module; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Map.Entry; import java.util.ServiceLoader; +import java.util.Set; import net.floodlightcontroller.core.IFloodlightService; @@ -21,8 +24,11 @@ public class FloodlightModuleLoader { LoggerFactory.getLogger(FloodlightModuleLoader.class); protected FloodlightModuleContext floodlightModuleContext; - protected Map<Class<? extends IFloodlightService>, - Collection<IFloodlightModule>> serviceMap; + protected Map<Class<? extends IFloodlightService>, + Collection<IFloodlightModule>> serviceMap; + protected Map<IFloodlightModule, + Collection<Class<? extends + IFloodlightService>>> moduleServiceMap; protected Map<String, IFloodlightModule> moduleNameMap; public FloodlightModuleLoader() { @@ -30,17 +36,13 @@ public class FloodlightModuleLoader { serviceMap = new HashMap<Class<? extends IFloodlightService>, Collection<IFloodlightModule>>(); + moduleServiceMap = + new HashMap<IFloodlightModule, + Collection<Class<? extends + IFloodlightService>>>(); moduleNameMap = new HashMap<String, IFloodlightModule>(); } - public IFloodlightModuleContext getModules() - throws FloodlightModuleException { - findAllModules(); - - - return floodlightModuleContext; - } - /** * Finds all IFloodlightModule(s) in the classpath. */ @@ -50,7 +52,9 @@ public class FloodlightModuleLoader { = ServiceLoader.load(IFloodlightModule.class); // Iterate for each module, iterate through and add it's services for (IFloodlightModule m : moduleLoader) { - logger.debug("Found module " + m.getClass().getName()); + if (logger.isDebugEnabled()) { + logger.debug("Found module " + m.getClass().getName()); + } // Set up moduleNameMap moduleNameMap.put(m.getClass().getCanonicalName(), m); @@ -59,6 +63,7 @@ public class FloodlightModuleLoader { Collection<Class<? extends IFloodlightService>> servs = m.getServices(); if (servs != null) { + moduleServiceMap.put(m, servs); for (Class<? extends IFloodlightService> s : servs) { Collection<IFloodlightModule> mods = serviceMap.get(s); @@ -72,76 +77,143 @@ public class FloodlightModuleLoader { } } - public void loadModulesFromConfig() throws FloodlightModuleException { + public IFloodlightModuleContext loadModulesFromConfig() + throws FloodlightModuleException { + logger.debug("Starting module loader"); findAllModules(); - initModule("net.floodlightcontroller.core.CoreModule"); - startupModules(); - /* - * first read modules.json - * go through modules 1 by 1 - * take name of module - * call loadModules(); - * call module.init(); - * - * for each module: - * call module.startUp(); - * - */ + Set<IFloodlightModule> moduleSet = new HashSet<IFloodlightModule>(); + Map<Class<? extends IFloodlightService>, IFloodlightModule> moduleMap = + new HashMap<Class<? extends IFloodlightService>, + IFloodlightModule>(); + + calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.core.CoreModule"); + calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.forwarding.Forwarding"); + calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher"); + calculateModuleDeps(moduleMap, moduleSet, "net.floodlightcontroller.core.OFMessageFilterManager"); + + initModules(moduleSet); + startupModules(moduleSet); + + return floodlightModuleContext; } - protected void startupModules() { - for (IFloodlightModule m : floodlightModuleContext.getModules()) { - m.startUp(floodlightModuleContext); - } + /** + * Add a module to the set of modules to load and register its services + * @param moduleMap the module map + * @param moduleSet the module set + * @param module the module to add + */ + protected void addModule(Map<Class<? extends IFloodlightService>, + IFloodlightModule> moduleMap, + Set<IFloodlightModule> moduleSet, + IFloodlightModule module) { + if (!moduleSet.contains(module)) { + Collection<Class<? extends IFloodlightService>> servs = + moduleServiceMap.get(module); + if (servs != null) { + for (Class<? extends IFloodlightService> c : servs) + moduleMap.put(c, module); + } + moduleSet.add(module); + } } + + /** + * Add a module and all its transitive dependencies + * @param moduleMap the module map + * @param moduleSet the module set + * @param moduleName the module name + * @throws FloodlightModuleException + */ + protected void calculateModuleDeps(Map<Class<? extends IFloodlightService>, + IFloodlightModule> moduleMap, + Set<IFloodlightModule> moduleSet, + String moduleName) throws FloodlightModuleException { - protected void initModule(String moduleName) throws FloodlightModuleException { - IFloodlightModule module = moduleNameMap.get(moduleName); - if (module == null) { - throw new FloodlightModuleException("Module " + - moduleName + " not found"); - } - Collection<? extends IFloodlightService> deps = - module.getDependencies(); - if (deps != null) { - for (IFloodlightService dep : deps) { - Class<? extends IFloodlightService> c = dep.getClass(); - IFloodlightService s = floodlightModuleContext.getService(c); - if (s == null) { - Collection<IFloodlightModule> mods = serviceMap.get(dep); - // Make sure only one module is loaded - if ((mods == null) || (mods.size() == 0)) { - throw new FloodlightModuleException("ERROR! Could not " + - "find IFloodlightModule that provides service " + - dep.getClass().toString()); - } else if (mods.size() == 1) { - // Recursively load the module's dependencies recursively - initModule(mods.iterator().next().getClass().toString()); - } else { - throw new FloodlightModuleException("ERROR! Found more " + - "than one IFloodlightModule that provides " + - "service " + dep.getClass().toString() + - ". Please resolve this in the config"); - } - } - // else it's already loaded - } - } - - // Get the module's service impls - Collection<IFloodlightService> simpls = - module.getServiceImpls(); + IFloodlightModule module = moduleNameMap.get(moduleName); + if (module == null) { + throw new FloodlightModuleException("Module " + + moduleName + " not found"); + } + + addModule(moduleMap, moduleSet, module); - // init the module - module.init(floodlightModuleContext); + Collection<Class<? extends IFloodlightService>> deps = + module.getDependencies(); - // add the module's services to the context - floodlightModuleContext.addModule(module); - if (simpls != null) { - for (IFloodlightService s : simpls) { - floodlightModuleContext.addService(s); + if (deps != null) { + for (Class<? extends IFloodlightService> c : deps) { + IFloodlightModule m = moduleMap.get(c); + if (m == null) { + Collection<IFloodlightModule> mods = serviceMap.get(c); + // Make sure only one module is loaded + if ((mods == null) || (mods.size() == 0)) { + throw new FloodlightModuleException("ERROR! Could not " + + "find an IFloodlightModule that provides service " + + c.toString()); + } else if (mods.size() == 1) { + IFloodlightModule mod = mods.iterator().next(); + calculateModuleDeps(moduleMap, moduleSet, + mod.getClass().getCanonicalName()); + } else { + throw new FloodlightModuleException("ERROR! Found more " + + "than one IFloodlightModule that provides " + + "service " + c.toString() + + ". Please resolve this in the config"); + } + } + } + } + } + + /** + * Allocate service implementations and then init all the modules + * @param moduleMap + * @throws FloodlightModuleException + */ + protected void initModules(Set<IFloodlightModule> moduleSet) + throws FloodlightModuleException { + for (IFloodlightModule module : moduleSet) { + // Get the module's service instance(s) + Map<Class<? extends IFloodlightService>, + IFloodlightService> simpls = module.getServiceImpls(); + + // add its services to the context + if (simpls != null) { + for (Entry<Class<? extends IFloodlightService>, + IFloodlightService> s : simpls.entrySet()) { + if (logger.isDebugEnabled()) { + logger.debug("Setting " + s.getValue() + + " as provider for " + + s.getKey().getCanonicalName()); + } + floodlightModuleContext.addService(s.getKey(), + s.getValue()); + } } } - } + for (IFloodlightModule module : moduleSet) { + // init the module + if (logger.isDebugEnabled()) { + logger.debug("Initializing " + + module.getClass().getCanonicalName()); + } + module.init(floodlightModuleContext); + } + } + + /** + * Call each loaded module's startup method + * @param moduleSet the module set to start up + */ + protected void startupModules(Set<IFloodlightModule> moduleSet) { + for (IFloodlightModule m : moduleSet) { + if (logger.isDebugEnabled()) { + logger.debug("Starting " + + m.getClass().getCanonicalName()); + } + m.startUp(floodlightModuleContext); + } + } } diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java index ee307fc77..aede7bec9 100644 --- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java +++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModule.java @@ -1,6 +1,7 @@ package net.floodlightcontroller.core.module; import java.util.Collection; +import java.util.Map; import net.floodlightcontroller.core.IFloodlightService; @@ -27,22 +28,32 @@ public interface IFloodlightModule { public Collection<Class<? extends IFloodlightService>> getServices(); - public Collection<IFloodlightService> getServiceImpls(); + /** + * Instantiate (as needed) and return objects that implement each + * of the services exported by this module. The map returned maps + * the implemented service to the object. The object could be the + * same object or different objects for different exported services. + * @return The map from service interface class to service implementation + */ + public Map<Class<? extends IFloodlightService>, + IFloodlightService> getServiceImpls(); /** * Get a list of Modules that this module depends on. The module system - * will ensure that each these dependencies is resolved before the subsequent calls to init(). - * - * @return + * will ensure that each these dependencies is resolved before the + * subsequent calls to init(). + * @return The Collection of IFloodlightServices that this module depnds + * on. */ - public Collection<? extends IFloodlightService> getDependencies(); + public Collection<Class<? extends IFloodlightService>> getDependencies(); /** * This is a hook for each module to do its <em>internal</em> initialization, * e.g., call setService(context.getService("Service")) * - * All module dependencies are resolved when this is called, but not every module is initialized. + * All module dependencies are resolved when this is called, but not every module + * is initialized. * * @param context * @throws FloodlightModuleException diff --git a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java index 6be257a52..75bcfb112 100644 --- a/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java +++ b/src/main/java/net/floodlightcontroller/core/module/IFloodlightModuleContext.java @@ -3,11 +3,12 @@ package net.floodlightcontroller.core.module; import net.floodlightcontroller.core.IFloodlightService; public interface IFloodlightModuleContext { - //TODO FIX THIS COMMENT - /** - * Retrieves a casted version of a module from the registry. - * @return The module casted to the correct type - */ - public IFloodlightService getService( - Class<? extends IFloodlightService> service); + /** + * Retrieves a casted version of a module from the registry. + * @param name The IFloodlightService object type + * @return The IFloodlightService + * @throws FloodlightModuleException If the module was not found + * or a ClassCastException was encountered. + */ + public <T extends IFloodlightService> T getServiceImpl(Class<T> service); } diff --git a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java index 2ef32f13d..0c880736b 100644 --- a/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/AllSwitchStatisticsResource.java @@ -23,7 +23,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.types.MacVlanPair; import org.openflow.protocol.OFFeaturesReply; @@ -80,7 +80,7 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { return model; } - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); Long[] switchDpids = floodlightProvider.getSwitches().keySet().toArray(new Long[0]); List<GetConcurrentStatsThread> activeThreads = new ArrayList<GetConcurrentStatsThread>(switchDpids.length); List<GetConcurrentStatsThread> pendingRemovalThreads = new ArrayList<GetConcurrentStatsThread>(); @@ -167,7 +167,7 @@ public class AllSwitchStatisticsResource extends SwitchResourceBase { } public void run() { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); if ((requestType == REQUESTTYPE.OFSTATS) && (statType != null)) { switchReply = getSwitchStatistics(switchId, statType); diff --git a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java index b2d903a6e..026382a6c 100644 --- a/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/ControllerSwitchesResource.java @@ -22,7 +22,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import org.restlet.resource.Get; @@ -37,7 +37,7 @@ public class ControllerSwitchesResource extends ServerResource { public List<Map<String, String>> retrieve() { List<Map<String, String>> switchIds = new ArrayList<Map<String, String>>(); - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); Map<Long, IOFSwitch> switches = floodlightProvider.getSwitches(); for (IOFSwitch s: switches.values()) { diff --git a/src/main/java/net/floodlightcontroller/core/web/CounterResource.java b/src/main/java/net/floodlightcontroller/core/web/CounterResource.java index 124cd5b16..fb680d7c9 100644 --- a/src/main/java/net/floodlightcontroller/core/web/CounterResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/CounterResource.java @@ -23,7 +23,7 @@ import java.util.Map; import java.util.Map.Entry; import net.floodlightcontroller.counter.CounterValue; -import net.floodlightcontroller.counter.ICounterService; +import net.floodlightcontroller.counter.ICounter; import org.restlet.resource.Get; @@ -35,12 +35,12 @@ public class CounterResource extends CounterResourceBase { Map<String, Object> model = new HashMap<String,Object>(); CounterValue v; if (counterTitle.equalsIgnoreCase("all")) { - Map<String, ICounterService> counters = this.counterStore.getAll(); + Map<String, ICounter> counters = this.counterStore.getAll(); if (counters != null) { - Iterator<Map.Entry<String, ICounterService>> it = + Iterator<Map.Entry<String, ICounter>> it = counters.entrySet().iterator(); while (it.hasNext()) { - Entry<String, ICounterService> entry = it.next(); + Entry<String, ICounter> entry = it.next(); String counterName = entry.getKey(); v = entry.getValue().getCounterValue(); @@ -52,7 +52,7 @@ public class CounterResource extends CounterResourceBase { } } } else { - ICounterService counter = this.counterStore.getCounter(counterTitle); + ICounter counter = this.counterStore.getCounter(counterTitle); if (counter != null) { v = counter.getCounterValue(); } else { diff --git a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java index e27b0ae31..f61cd079f 100644 --- a/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java +++ b/src/main/java/net/floodlightcontroller/core/web/CounterResourceBase.java @@ -17,18 +17,18 @@ package net.floodlightcontroller.core.web; -import net.floodlightcontroller.counter.CounterStore; +import net.floodlightcontroller.counter.ICounterStoreService; import org.restlet.resource.ResourceException; import org.restlet.resource.ServerResource; public class CounterResourceBase extends ServerResource { - protected CounterStore counterStore; + protected ICounterStoreService counterStore; @Override protected void doInit() throws ResourceException { super.doInit(); counterStore = - (CounterStore)getContext().getAttributes().get("counterStore"); + (ICounterStoreService)getContext().getAttributes().get("counterStore"); } } diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java index c3d8ae6ac..2b8166343 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchClustersResource.java @@ -23,7 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import org.openflow.util.HexString; @@ -36,7 +36,7 @@ import org.restlet.resource.ServerResource; public class SwitchClustersResource extends ServerResource { @Get("json") public Map<String, List<String>> retrieve() { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); Map<String, List<String>> switchClusterMap = new HashMap<String, List<String>>(); for (Entry<Long, IOFSwitch> entry : floodlightProvider.getSwitches().entrySet()) { Long clusterDpid = entry.getValue().getSwitchClusterId(); diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java index dbce9f088..39d5db579 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterCategoriesResource.java @@ -26,9 +26,9 @@ import java.util.Map; import org.openflow.util.HexString; import org.restlet.resource.Get; -import net.floodlightcontroller.core.IFloodlightProvider; -import net.floodlightcontroller.counter.CounterStore; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.counter.CounterStore.NetworkLayer; +import net.floodlightcontroller.counter.ICounterStoreService; /** * Get the counter categories for a particular switch @@ -37,7 +37,7 @@ import net.floodlightcontroller.counter.CounterStore.NetworkLayer; public class SwitchCounterCategoriesResource extends CounterResourceBase { @Get("json") public Map<String, Object> retrieve() { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); HashMap<String,Object> model = new HashMap<String,Object>(); String switchID = (String) getRequestAttributes().get("switchId"); @@ -69,7 +69,7 @@ public class SwitchCounterCategoriesResource extends CounterResourceBase { try { counterName = URLDecoder.decode(counterName, "UTF-8"); layer = URLDecoder.decode(layer, "UTF-8"); - fullCounterName = switchID + CounterStore.TitleDelimitor + counterName; + fullCounterName = switchID + ICounterStoreService.TitleDelimitor + counterName; } catch (UnsupportedEncodingException e) { //Just leave counterTitle undecoded if there is an issue - fail silently } diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java index a371cd892..e9625fca3 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchCounterResource.java @@ -25,9 +25,9 @@ import java.util.Map; import org.openflow.util.HexString; import org.restlet.resource.Get; -import net.floodlightcontroller.core.IFloodlightProvider; -import net.floodlightcontroller.counter.CounterStore; -import net.floodlightcontroller.counter.ICounterService; +import net.floodlightcontroller.core.IFloodlightProviderService; +import net.floodlightcontroller.counter.ICounter; +import net.floodlightcontroller.counter.ICounterStoreService; /** * Get counters for a particular switch @@ -36,7 +36,7 @@ import net.floodlightcontroller.counter.ICounterService; public class SwitchCounterResource extends CounterResourceBase { @Get("json") public Map<String, Object> retrieve() { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); HashMap<String,Object> model = new HashMap<String,Object>(); String switchID = (String) getRequestAttributes().get("switchId"); @@ -63,12 +63,12 @@ public class SwitchCounterResource extends CounterResourceBase { try { counterName = URLDecoder.decode(counterName, "UTF-8"); fullCounterName = - switchID + CounterStore.TitleDelimitor + counterName; + switchID + ICounterStoreService.TitleDelimitor + counterName; } catch (UnsupportedEncodingException e) { //Just leave counterTitle undecoded if there is an issue - fail silently } - ICounterService counter = this.counterStore.getCounter(fullCounterName); + ICounter counter = this.counterStore.getCounter(fullCounterName); Map<String, Long> sample = new HashMap<String, Long> (); if (counter != null) { sample.put(counter.getCounterDate().toString(), diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java index 8c59a3407..3ac4e1e43 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchResourceBase.java @@ -26,7 +26,7 @@ import java.util.Map; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.types.MacVlanPair; @@ -66,7 +66,7 @@ public class SwitchResourceBase extends ServerResource { } protected List<OFStatistics> getSwitchStatistics(long switchId, OFStatisticsType statType) { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); IOFSwitch sw = floodlightProvider.getSwitches().get(switchId); Future<List<OFStatistics>> future; @@ -132,7 +132,7 @@ public class SwitchResourceBase extends ServerResource { * @return A list of switch table entries */ protected List<Map<String, Object>> getSwitchTableJson(long switchId) { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); IOFSwitch sw = floodlightProvider.getSwitches().get(switchId); List<Map<String, Object>> switchTableJson = null; diff --git a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java index 0f10c2538..42e5feafe 100644 --- a/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java +++ b/src/main/java/net/floodlightcontroller/core/web/SwitchStatisticsResource.java @@ -21,7 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import org.openflow.protocol.OFFeaturesReply; @@ -42,7 +42,7 @@ public class SwitchStatisticsResource extends SwitchResourceBase { @Get("json") public Map<String, Object> retrieve() { - IFloodlightProvider floodlightProvider = (IFloodlightProvider)getApplication(); + IFloodlightProviderService floodlightProvider = (IFloodlightProviderService)getApplication(); HashMap<String,Object> result = new HashMap<String,Object>(); List<OFStatistics> values = null; diff --git a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java b/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java index 7a7443d0d..cdec1e0ed 100644 --- a/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java +++ b/src/main/java/net/floodlightcontroller/counter/ConcurrentCounter.java @@ -53,7 +53,7 @@ import net.floodlightcontroller.counter.CounterValue.CounterType; * @author kyle * */ -public class ConcurrentCounter implements ICounterService { +public class ConcurrentCounter implements ICounter { protected static final Map<DateSpan, Integer> MAX_HISTORY = new HashMap<DateSpan, Integer>(); static { @@ -110,7 +110,7 @@ public class ConcurrentCounter implements ICounterService { * @param startDate * @return */ - public static ICounterService createCounter(Date startDate) { + public static ICounter createCounter(Date startDate) { ConcurrentCounter cc = new ConcurrentCounter(startDate); ConcurrentCounter.liveCounters.add(cc); return cc; diff --git a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java b/src/main/java/net/floodlightcontroller/counter/CountBuffer.java index 7bd26a7c1..fa45862e8 100644 --- a/src/main/java/net/floodlightcontroller/counter/CountBuffer.java +++ b/src/main/java/net/floodlightcontroller/counter/CountBuffer.java @@ -19,7 +19,7 @@ package net.floodlightcontroller.counter; import java.util.Date; -import net.floodlightcontroller.counter.ICounterService.DateSpan; +import net.floodlightcontroller.counter.ICounter.DateSpan; /** diff --git a/src/main/java/net/floodlightcontroller/counter/CountSeries.java b/src/main/java/net/floodlightcontroller/counter/CountSeries.java index 0f06e8258..c94e5bc61 100644 --- a/src/main/java/net/floodlightcontroller/counter/CountSeries.java +++ b/src/main/java/net/floodlightcontroller/counter/CountSeries.java @@ -20,7 +20,7 @@ package net.floodlightcontroller.counter; import java.util.Arrays; import java.util.Date; -import net.floodlightcontroller.counter.ICounterService.DateSpan; +import net.floodlightcontroller.counter.ICounter.DateSpan; /** * Simple immutable class to store a series of historic counter values diff --git a/src/main/java/net/floodlightcontroller/counter/CounterStore.java b/src/main/java/net/floodlightcontroller/counter/CounterStore.java index a2c31e38b..585afc6a3 100644 --- a/src/main/java/net/floodlightcontroller/counter/CounterStore.java +++ b/src/main/java/net/floodlightcontroller/counter/CounterStore.java @@ -35,18 +35,13 @@ import javax.annotation.PostConstruct; * @author kyle * */ -public class CounterStore { - public final static String TitleDelimitor = "__"; - - /** L2 EtherType subCategories */ - public final static String L3ET_IPV4 = "L3_IPv4"; - +public class CounterStore implements ICounterStoreService { public enum NetworkLayer { L3, L4 } protected class CounterEntry { - protected ICounterService counter; + protected ICounter counter; String title; } @@ -56,8 +51,8 @@ public class CounterStore { protected Map<String, CounterEntry> nameToCEIndex = new ConcurrentHashMap<String, CounterEntry>(); - protected ICounterService heartbeatCounter; - protected ICounterService randomCounter; + protected ICounter heartbeatCounter; + protected ICounter randomCounter; /** * Counter Categories grouped by network layers @@ -121,10 +116,7 @@ public class CounterStore { return fullCounterName; } - /** - * Retrieve a list of subCategories by counterName. - * null if nothing. - */ + @Override public List<String> getAllCategories(String counterName, NetworkLayer layer) { if (layeredCategories.containsKey(layer)) { Map<String, List<String>> counterToCategories = layeredCategories.get(layer); @@ -135,17 +127,10 @@ public class CounterStore { return null; } - /** - * Create a new ICounter and set the title. Note that the title must be unique, otherwise this will - * throw an IllegalArgumentException. - * - * @param key - * @param type - * @return - */ - public ICounterService createCounter(String key, CounterValue.CounterType type) { + @Override + public ICounter createCounter(String key, CounterValue.CounterType type) { CounterEntry ce; - ICounterService c; + ICounter c; if (!nameToCEIndex.containsKey(key)) { c = SimpleCounter.createCounter(new Date(), type); @@ -175,10 +160,8 @@ public class CounterStore { }}, 100, 100, TimeUnit.MILLISECONDS); } - /** - * Retrieves a counter with the given title, or null if none can be found. - */ - public ICounterService getCounter(String key) { + @Override + public ICounter getCounter(String key) { CounterEntry counter = nameToCEIndex.get(key); if (counter != null) { return counter.counter; @@ -187,16 +170,15 @@ public class CounterStore { } } - /** - * Returns an immutable map of title:counter with all of the counters in the store. - * - * (Note - this method may be slow - primarily for debugging/UI) + /* (non-Javadoc) + * @see net.floodlightcontroller.counter.ICounterStoreService#getAll() */ - public Map<String, ICounterService> getAll() { - Map<String, ICounterService> ret = new ConcurrentHashMap<String, ICounterService>(); + @Override + public Map<String, ICounter> getAll() { + Map<String, ICounter> ret = new ConcurrentHashMap<String, ICounter>(); for(Map.Entry<String, CounterEntry> counterEntry : this.nameToCEIndex.entrySet()) { String key = counterEntry.getKey(); - ICounterService counter = counterEntry.getValue().counter; + ICounter counter = counterEntry.getValue().counter; ret.put(key, counter); } return ret; diff --git a/src/main/java/net/floodlightcontroller/counter/ICounterService.java b/src/main/java/net/floodlightcontroller/counter/ICounter.java similarity index 93% rename from src/main/java/net/floodlightcontroller/counter/ICounterService.java rename to src/main/java/net/floodlightcontroller/counter/ICounter.java index 242273b54..625bebdc3 100644 --- a/src/main/java/net/floodlightcontroller/counter/ICounterService.java +++ b/src/main/java/net/floodlightcontroller/counter/ICounter.java @@ -23,13 +23,11 @@ package net.floodlightcontroller.counter; import java.util.Date; -import net.floodlightcontroller.core.IFloodlightService; - /** * @author kyle * */ -public interface ICounterService extends IFloodlightService { +public interface ICounter { /** * Most commonly used method diff --git a/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java new file mode 100644 index 000000000..3303198f7 --- /dev/null +++ b/src/main/java/net/floodlightcontroller/counter/ICounterStoreService.java @@ -0,0 +1,43 @@ +package net.floodlightcontroller.counter; + +import java.util.List; +import java.util.Map; + +import net.floodlightcontroller.core.IFloodlightService; +import net.floodlightcontroller.counter.CounterStore.NetworkLayer; + +public interface ICounterStoreService extends IFloodlightService { + + public final static String TitleDelimitor = "__"; + /** L2 EtherType subCategories */ + public final static String L3ET_IPV4 = "L3_IPv4"; + + /** + * Retrieve a list of subCategories by counterName. + * null if nothing. + */ + public List<String> getAllCategories(String counterName, + NetworkLayer layer); + + /** + * Create a new ICounter and set the title. Note that the title must be + * unique, otherwise this will throw an IllegalArgumentException. + * + * @param key + * @param type + * @return + */ + public ICounter createCounter(String key, CounterValue.CounterType type); + + /** + * Retrieves a counter with the given title, or null if none can be found. + */ + public ICounter getCounter(String key); + + /** + * Returns an immutable map of title:counter with all of the counters in the store. + * + * (Note - this method may be slow - primarily for debugging/UI) + */ + public Map<String, ICounter> getAll(); +} diff --git a/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java index 34615ee09..d4aadaf83 100644 --- a/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java +++ b/src/main/java/net/floodlightcontroller/counter/SimpleCounter.java @@ -32,7 +32,7 @@ import java.util.Date; * @author Kanzhe * */ -public class SimpleCounter implements ICounterService { +public class SimpleCounter implements ICounter { protected CounterValue counter; protected Date samplingTime; @@ -44,7 +44,7 @@ public class SimpleCounter implements ICounterService { * @param startDate * @return */ - public static ICounterService createCounter(Date startDate, CounterValue.CounterType type) { + public static ICounter createCounter(Date startDate, CounterValue.CounterType type) { SimpleCounter cc = new SimpleCounter(startDate, type); return cc; diff --git a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java index e7e6c6859..184a289a7 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/IDeviceManagerService.java @@ -67,4 +67,10 @@ public interface IDeviceManagerService extends IFloodlightService { * @return */ public List<Device> getDevices(); + + /** + * Adds a listener to listen for IDeviceManagerServices notifications + * @param listener The listener that wants the notifications + */ + public void addListener(IDeviceManagerAware listener); } diff --git a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java index 88dc0ab7f..2ddc0772d 100755 --- a/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java +++ b/src/main/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImpl.java @@ -25,6 +25,7 @@ import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Date; import java.util.HashMap; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -39,10 +40,14 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.util.SingletonTask; import net.floodlightcontroller.devicemanager.Device; import net.floodlightcontroller.devicemanager.DeviceAttachmentPoint; @@ -85,12 +90,7 @@ import org.slf4j.LoggerFactory; * @author David Erickson (daviderickson@cs.stanford.edu) */ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListener, - IOFSwitchListener, ITopologyListener { - protected static Logger log = - LoggerFactory.getLogger(DeviceManagerImpl.class); - - protected IFloodlightProvider floodlightProvider; - + IOFSwitchListener, ITopologyListener, IFloodlightModule { /** * Class to maintain all the device manager maps which consists of four * main maps. @@ -497,8 +497,10 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe // Now add this updated device to the maps, which will replace // the old copy updateMaps(dCopy); - log.debug("Device 1 {}", d); - log.debug("Device 2 {}", dCopy); + if (log.isDebugEnabled()) { + log.debug("Device 1 {}", d); + log.debug("Device 2 {}", dCopy); + } removeAttachmentPointFromStorage(d, dap); d = null; // to catch if anyone is using this reference return true; @@ -540,12 +542,17 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe return devMgrMaps; } + protected static Logger log = + LoggerFactory.getLogger(DeviceManagerImpl.class); + protected Set<IDeviceManagerAware> deviceManagerAware; + protected LinkedList<Update> updates; protected ReentrantReadWriteLock lock; protected volatile boolean shuttingDown = false; + // Our dependencies + protected IFloodlightProviderService floodlightProvider; protected ITopologyService topology; - protected LinkedList<Update> updates; protected IStorageSourceService storageSource; protected Runnable deviceAgingTimer; @@ -627,23 +634,6 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe new EventHistory<OFMatch>("Pakcet-In"); } - public void startUp() { - ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor(); - deviceUpdateTask = new SingletonTask(ses, new DeviceUpdateWorker()); - - floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); - floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this); - floodlightProvider.addOFSwitchListener(this); - - /* - * Device and storage aging. - */ - enableDeviceAgingTimer(); - - // Read all our device state (MACs, IPs, attachment points) from storage - readAllDeviceStateFromStorage(); - } - public void shutDown() { shuttingDown = true; floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this); @@ -778,8 +768,8 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe Long dlAddr = Ethernet.toLong(match.getDataLayerSource()); Short vlan = match.getDataLayerVirtualLan(); if (vlan < 0) vlan = null; - Ethernet eth = IFloodlightProvider.bcStore.get( - cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD); + Ethernet eth = IFloodlightProviderService.bcStore.get( + cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD); int nwSrc = getSrcNwAddr(eth, dlAddr); Device device = devMgrMaps.getDeviceByDataLayerAddr(dlAddr); Date currentDate = new Date(); // TODO, @@ -1068,7 +1058,7 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe /** * @param floodlightProvider the floodlightProvider to set */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { + public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } @@ -1196,29 +1186,9 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe public void removedLink(IOFSwitch src, short srcPort, IOFSwitch dst, short dstPort) { + // no-op } - - /** - * @param deviceManagerAware the deviceManagerAware to set - */ - public void setDeviceManagerAware(Set<IDeviceManagerAware> - deviceManagerAware) { - this.deviceManagerAware = deviceManagerAware; - } - - public void setStorageSource(IStorageSourceService storageSource) { - this.storageSource = storageSource; - storageSource.createTable(DEVICE_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName( - DEVICE_TABLE_NAME, MAC_COLUMN_NAME); - storageSource.createTable(DEVICE_ATTACHMENT_POINT_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName( - DEVICE_ATTACHMENT_POINT_TABLE_NAME, ID_COLUMN_NAME); - storageSource.createTable(DEVICE_NETWORK_ADDRESS_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName( - DEVICE_NETWORK_ADDRESS_TABLE_NAME, ID_COLUMN_NAME); - } - + /** * Process device manager aware updates. Call without any lock held */ @@ -1954,4 +1924,97 @@ public class DeviceManagerImpl implements IDeviceManagerService, IOFMessageListe private void evHistPktIn(OFMatch packetIn) { evHistDevMgrPktIn.put(packetIn, EvAction.PKT_IN); } + + // IFloodlightModule methods + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IDeviceManagerService.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(IDeviceManagerService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IFloodlightProviderService.class); + l.add(IStorageSourceService.class); + l.add(ITopologyService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + // Wire up all our dependencies + floodlightProvider = + context.getServiceImpl(IFloodlightProviderService.class); + topology = + context.getServiceImpl(ITopologyService.class); + storageSource = + context.getServiceImpl(IStorageSourceService.class); + + // We create this here because there is no ordering guarantee + this.deviceManagerAware = new HashSet<IDeviceManagerAware>(); + } + + @Override + public void startUp(FloodlightModuleContext context) { + // This is our 'constructor' + + // Create our data structures + this.devMgrMaps = new DevMgrMaps(); + this.lock = new ReentrantReadWriteLock(); + this.updates = new LinkedList<Update>(); + this.evHistDevMgrAttachPt = + new EventHistory<EventHistoryAttachmentPoint>("Attachment-Point"); + this.evHistDevMgrPktIn = + new EventHistory<OFMatch>("Pakcet-In"); + + // Register to get updates from topology + topology.addListener(this); + + // Create our database tables + storageSource.createTable(DEVICE_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName( + DEVICE_TABLE_NAME, MAC_COLUMN_NAME); + storageSource.createTable(DEVICE_ATTACHMENT_POINT_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName( + DEVICE_ATTACHMENT_POINT_TABLE_NAME, ID_COLUMN_NAME); + storageSource.createTable(DEVICE_NETWORK_ADDRESS_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName( + DEVICE_NETWORK_ADDRESS_TABLE_NAME, ID_COLUMN_NAME); + + ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor(); + deviceUpdateTask = new SingletonTask(ses, new DeviceUpdateWorker()); + + // Register for the OpenFlow messages we want + floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); + floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this); + // Register for switch events + floodlightProvider.addOFSwitchListener(this); + // Device and storage aging. + enableDeviceAgingTimer(); + // Read all our device state (MACs, IPs, attachment points) from storage + readAllDeviceStateFromStorage(); + } + + @Override + public void addListener(IDeviceManagerAware listener) { + deviceManagerAware.add(listener); + } } diff --git a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java index 7fa76f2f9..76d165fd5 100644 --- a/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java +++ b/src/main/java/net/floodlightcontroller/forwarding/Forwarding.java @@ -20,17 +20,27 @@ package net.floodlightcontroller.forwarding; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.List; +import java.util.Map; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFSwitch; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; +import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.devicemanager.Device; import net.floodlightcontroller.devicemanager.DeviceAttachmentPoint; +import net.floodlightcontroller.devicemanager.IDeviceManagerService; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.routing.ForwardingBase; import net.floodlightcontroller.routing.IRoutingDecision; +import net.floodlightcontroller.routing.IRoutingEngineService; import net.floodlightcontroller.routing.Route; +import net.floodlightcontroller.topology.ITopologyService; import net.floodlightcontroller.topology.LinkInfo; import net.floodlightcontroller.topology.SwitchPortTuple; @@ -45,13 +55,13 @@ import org.openflow.util.HexString; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class Forwarding extends ForwardingBase { +public class Forwarding extends ForwardingBase implements IFloodlightModule { protected static Logger log = LoggerFactory.getLogger(Forwarding.class); @Override public Command processPacketInMessage(IOFSwitch sw, OFPacketIn pi, IRoutingDecision decision, FloodlightContext cntx) { - Ethernet eth = IFloodlightProvider.bcStore.get(cntx, - IFloodlightProvider.CONTEXT_PI_PAYLOAD); + Ethernet eth = IFloodlightProviderService.bcStore.get(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD); if (eth.isBroadcast() || eth.isMulticast()) { // For now we treat multicast as broadcast doFlood(sw, pi, cntx); @@ -146,8 +156,8 @@ public class Forwarding extends ForwardingBase { Route route = routingEngine.getRoute(srcSw.getId(), dstSw.getId()); if ((route != null) || validLocalHop(srcDap.getSwitchPort(), dstDap.getSwitchPort())) { int bufferId = OFPacketOut.BUFFER_ID_NONE; - if (log.isTraceEnabled()) { - log.trace("pushRoute match={} route={} destination={}:{}", + if (log.isDebugEnabled()) { + log.debug("pushRoute match={} route={} destination={}:{}", new Object[] {match, route, dstDap.getSwitchPort().getSw(), dstDap.getSwitchPort().getPort()}); } @@ -244,4 +254,49 @@ public class Forwarding extends ForwardingBase { return srcTuple.getSw().getId() == dstTuple.getSw().getId() && srcTuple.getPort() != dstTuple.getPort(); } + + // IFloodlightModule methods + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + // We don't export any services + return null; + } + + @Override + public Map<Class<? extends IFloodlightService>, IFloodlightService> + getServiceImpls() { + // We don't have any services + return null; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IFloodlightProviderService.class); + l.add(IDeviceManagerService.class); + l.add(IRoutingEngineService.class); + l.add(ITopologyService.class); + l.add(ICounterStoreService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) throws FloodlightModuleException { + this.setFloodlightProvider(context.getServiceImpl(IFloodlightProviderService.class)); + this.setDeviceManager(context.getServiceImpl(IDeviceManagerService.class)); + this.setRoutingEngine(context.getServiceImpl(IRoutingEngineService.class)); + this.setTopology(context.getServiceImpl(ITopologyService.class)); + this.setCounterStore(context.getServiceImpl(ICounterStoreService.class)); + } + + @Override + public void startUp(FloodlightModuleContext context) { + if (log.isDebugEnabled()) { + log.debug("Starting " + this.getClass().getCanonicalName()); + } + + super.startUp(); + } } diff --git a/src/main/java/net/floodlightcontroller/hub/Hub.java b/src/main/java/net/floodlightcontroller/hub/Hub.java index 29b26f316..db20e43f0 100644 --- a/src/main/java/net/floodlightcontroller/hub/Hub.java +++ b/src/main/java/net/floodlightcontroller/hub/Hub.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.Collections; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; @@ -43,12 +43,12 @@ import org.slf4j.LoggerFactory; public class Hub implements IOFMessageListener { protected static Logger log = LoggerFactory.getLogger(Hub.class); - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; /** * @param floodlightProvider the floodlightProvider to set */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { + public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } diff --git a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java index a03c4df2b..f677a76f7 100644 --- a/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java +++ b/src/main/java/net/floodlightcontroller/learningswitch/LearningSwitch.java @@ -35,12 +35,13 @@ import java.util.Arrays; import java.util.List; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.counter.CounterStore; import net.floodlightcontroller.counter.CounterValue; -import net.floodlightcontroller.counter.ICounterService; +import net.floodlightcontroller.counter.ICounter; +import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.packet.Ethernet; import org.openflow.protocol.OFError; @@ -62,8 +63,8 @@ import org.slf4j.LoggerFactory; public class LearningSwitch implements IOFMessageListener { protected static Logger log = LoggerFactory.getLogger(LearningSwitch.class); - protected IFloodlightProvider floodlightProvider; - protected CounterStore counterStore; + protected IFloodlightProviderService floodlightProvider; + protected ICounterStoreService counterStore; // flow-mod - for use in the cookie public static final int LEARNING_SWITCH_APP_ID = 1; @@ -84,15 +85,15 @@ public class LearningSwitch implements IOFMessageListener { /** * @param floodlightProvider the floodlightProvider to set */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { + public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } - public CounterStore getCounterStore() { + public ICounterStoreService getCounterStore() { return counterStore; } - public void setCounterStore(CounterStore counterStore) { + public void setCounterStore(ICounterStoreService counterStore) { this.counterStore = counterStore; } @@ -142,7 +143,7 @@ public class LearningSwitch implements IOFMessageListener { // flowmod is per switch. portid = -1 String counterName = CounterStore.createCounterName(sw.getStringId(), -1, packetName); try { - ICounterService counter = counterStore.getCounter(counterName); + ICounter counter = counterStore.getCounter(counterName); if (counter == null) { counter = counterStore.createCounter(counterName, CounterValue.CounterType.LONG); } diff --git a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java index f59991ba4..b09705223 100644 --- a/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java +++ b/src/main/java/net/floodlightcontroller/routing/ForwardingBase.java @@ -22,19 +22,20 @@ import java.util.ArrayList; import java.util.List; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.util.AppCookie; import net.floodlightcontroller.counter.CounterStore; import net.floodlightcontroller.counter.CounterValue; -import net.floodlightcontroller.counter.ICounterService; +import net.floodlightcontroller.counter.ICounter; +import net.floodlightcontroller.counter.ICounterStoreService; import net.floodlightcontroller.devicemanager.Device; import net.floodlightcontroller.devicemanager.DeviceNetworkAddress; import net.floodlightcontroller.devicemanager.IDeviceManagerService; import net.floodlightcontroller.devicemanager.IDeviceManagerAware; import net.floodlightcontroller.packet.Ethernet; -import net.floodlightcontroller.routing.IRoutingEngine; +import net.floodlightcontroller.routing.IRoutingEngineService; import net.floodlightcontroller.routing.IRoutingDecision; import net.floodlightcontroller.routing.Link; import net.floodlightcontroller.routing.Route; @@ -60,24 +61,21 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag public static final short FLOWMOD_DEFAULT_HARD_TIMEOUT=5; // in seconds - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; protected IDeviceManagerService deviceManager; - protected IRoutingEngine routingEngine; + protected IRoutingEngineService routingEngine; protected ITopologyService topology; - protected CounterStore counterStore; + protected ICounterStoreService counterStore; // flow-mod - for use in the cookie public static final int FORWARDING_APP_ID = 2; // TODO: This must be managed by a global APP_ID class public void startUp() { + deviceManager.addListener(this); floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); } - public void shutDown() { - floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this); - } - @Override public String getName() { return "forwarding"; @@ -117,7 +115,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag // flowmod is per switch. portid = -1 String counterName = CounterStore.createCounterName(sw.getStringId(), -1, packetName); try { - ICounterService counter = counterStore.getCounter(counterName); + ICounter counter = counterStore.getCounter(counterName); if (counter == null) { counter = counterStore.createCounter(counterName, CounterValue.CounterType.LONG); } @@ -291,7 +289,7 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag } } - public static boolean blockHost(IFloodlightProvider floodlightProvider, + public static boolean blockHost(IFloodlightProviderService floodlightProvider, SwitchPortTuple sw_tup, long host_mac, short hardTimeout) { @@ -335,14 +333,14 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag /** * @param floodlightProvider the floodlightProvider to set */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { + public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) { this.floodlightProvider = floodlightProvider; } /** * @param routingEngine the routingEngine to set */ - public void setRoutingEngine(IRoutingEngine routingEngine) { + public void setRoutingEngine(IRoutingEngineService routingEngine) { this.routingEngine = routingEngine; } @@ -360,11 +358,11 @@ public abstract class ForwardingBase implements IOFMessageListener, IDeviceManag this.topology = topology; } - public CounterStore getCounterStore() { + public ICounterStoreService getCounterStore() { return counterStore; } - public void setCounterStore(CounterStore counterStore) { + public void setCounterStore(ICounterStoreService counterStore) { this.counterStore = counterStore; } diff --git a/src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java b/src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java similarity index 94% rename from src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java rename to src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java index 1a04ebbab..1b5e857f5 100644 --- a/src/main/java/net/floodlightcontroller/routing/IRoutingEngine.java +++ b/src/main/java/net/floodlightcontroller/routing/IRoutingEngineService.java @@ -17,6 +17,7 @@ package net.floodlightcontroller.routing; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.routing.Route; @@ -25,7 +26,7 @@ import net.floodlightcontroller.routing.Route; * * @author David Erickson (daviderickson@cs.stanford.edu) */ -public interface IRoutingEngine { +public interface IRoutingEngineService extends IFloodlightService { public Route getRoute(IOFSwitch src, IOFSwitch dst); public Route getRoute(Long srcDpid, Long dstDpid); diff --git a/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java b/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java index d212e69f4..fcf2a463f 100644 --- a/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java +++ b/src/main/java/net/floodlightcontroller/routing/dijkstra/RoutingImpl.java @@ -20,8 +20,11 @@ */ package net.floodlightcontroller.routing.dijkstra; +import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; +import java.util.Map; import java.util.PriorityQueue; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -29,20 +32,26 @@ import org.openflow.protocol.OFPhysicalPort.OFPortState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFSwitch; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.routing.BroadcastTree; -import net.floodlightcontroller.routing.IRoutingEngine; +import net.floodlightcontroller.routing.IRoutingEngineService; import net.floodlightcontroller.routing.Link; import net.floodlightcontroller.routing.Route; import net.floodlightcontroller.routing.RouteId; import net.floodlightcontroller.topology.ITopologyListener; +import net.floodlightcontroller.topology.ITopologyService; /** * Floodlight component to find shortest paths based on dijkstra's algorithm * * @author Mandeep Dhami (mandeep.dhami@bigswitch.com) */ -public class RoutingImpl implements IRoutingEngine, ITopologyListener { +public class RoutingImpl + implements IRoutingEngineService, ITopologyListener, IFloodlightModule { public static final int MAX_LINK_WEIGHT = 1000; public static final int MAX_PATH_WEIGHT = Integer.MAX_VALUE - MAX_LINK_WEIGHT - 1; @@ -54,17 +63,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener { protected HashMap<Long, HashMap<Long, Link>> nexthoplinkmaps; protected HashMap<Long, HashMap<Long, Long>> nexthopnodemaps; protected LRUHashMap<RouteId, Route> pathcache; - - public RoutingImpl() { - lock = new ReentrantReadWriteLock(); - - network = new HashMap<Long, HashMap<Link, Link>>(); - nexthoplinkmaps = new HashMap<Long, HashMap<Long, Link>>(); - nexthopnodemaps = new HashMap<Long, HashMap<Long, Long>>(); - pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE); - - log.info("Initialized Dijkstra RouterImpl"); - } + protected ITopologyService topology; @Override public boolean routeExists(Long srcId, Long dstId) { @@ -120,7 +119,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener { } lock.readLock().unlock(); - log.debug("getRoute: {} -> {}", id, result); + if (log.isDebugEnabled()) { + log.debug("getRoute: {} -> {}", id, result); + } return result; } @@ -151,7 +152,9 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener { Route result = null; if (path != null) result = new Route(id, path); - log.debug("buildroute: {}", result); + if (log.isDebugEnabled()) { + log.debug("buildroute: {}", result); + } return result; } @@ -312,10 +315,7 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener { BroadcastTree ret = new BroadcastTree(nexthoplinks, nexthopnodes); return ret; } - - public void startUp() {} - public void shutDown() {} - + @Override public void clusterMerged() { // no-op @@ -326,4 +326,54 @@ public class RoutingImpl implements IRoutingEngine, ITopologyListener { // Ignored by RoutingImpl } + // IFloodlightModule + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IRoutingEngineService.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(IRoutingEngineService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(ITopologyService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + topology = context.getServiceImpl(ITopologyService.class); + } + + @Override + public void startUp(FloodlightModuleContext context) { + // Our 'constructor' + lock = new ReentrantReadWriteLock(); + network = new HashMap<Long, HashMap<Link, Link>>(); + nexthoplinkmaps = new HashMap<Long, HashMap<Long, Link>>(); + nexthopnodemaps = new HashMap<Long, HashMap<Long, Long>>(); + pathcache = new LRUHashMap<RouteId, Route>(PATH_CACHE_SIZE); + + // Register to get updates from topology + topology.addListener(this); + + log.info("Initialized Dijkstra RouterImpl"); + } } diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java index f25c06fd8..e24c7b9cc 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java @@ -20,6 +20,7 @@ package net.floodlightcontroller.staticflowentry; import java.util.HashMap; import java.util.List; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFSwitch; import org.openflow.protocol.OFFlowMod; @@ -27,7 +28,7 @@ import org.openflow.protocol.OFFlowMod; * Represents the parts of the staticflowentry that are exposed as a service to other floodlight apps * */ -public interface IStaticFlowEntryPusherService { +public interface IStaticFlowEntryPusherService extends IFloodlightService { /** * Pushes a flow-mod to this switch as a one-time push * diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java index e280e7b55..32a4f0178 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java @@ -24,16 +24,22 @@ package net.floodlightcontroller.staticflowentry; import java.io.IOException; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.regex.Matcher; import java.util.regex.Pattern; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; import org.codehaus.jackson.JsonParseException; import org.codehaus.jackson.JsonParser; @@ -51,7 +57,8 @@ import org.openflow.util.U16; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOFSwitchListener { +public class StaticFlowEntryPusher + implements IStaticFlowEntryPusherService, IOFSwitchListener, IFloodlightModule { // Utility data structure private class FlowModFields { @@ -63,32 +70,18 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOF } protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusher.class); - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; protected ArrayList<String> flowmodList; protected ArrayList<IOFSwitch> activeSwitches; protected HashMap<Long, HashMap<String, OFFlowMod>> flowmods; protected int pushEntriesFrequency = 25; // seconds protected Runnable pushEntriesTimer; - - public StaticFlowEntryPusher() { - flowmodList = new ArrayList<String>(); - flowmods = new HashMap<Long, HashMap<String, OFFlowMod>>(); - activeSwitches = new ArrayList<IOFSwitch>(); - } @Override public String getName() { return "staticflowentry"; } - - public IFloodlightProvider getFloodlightProvider() { - return floodlightProvider; - } - - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { - this.floodlightProvider = floodlightProvider; - } /** * Gets the static flow entry push interval @@ -604,7 +597,68 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOF return entryCookie; } - public void startUp() { + /** + * Pushes all entries associated with all switches (from the store) + */ + protected void pushAllEntries() { + for (IOFSwitch sw : activeSwitches) { + for (OFFlowMod fm : getEntries(sw).values()) { + pushEntry(sw, fm); + } + } + } + + public void shutDown() { + log.info("shutdown"); + pushEntriesTimer = null; + floodlightProvider.removeOFSwitchListener(this); + } + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IStaticFlowEntryPusherService.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(IStaticFlowEntryPusherService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IFloodlightProviderService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + // Wire up all our dependencies + floodlightProvider = + context.getServiceImpl(IFloodlightProviderService.class); + } + + @Override + public void startUp(FloodlightModuleContext context) { + // This is our 'constructor' + if (log.isDebugEnabled()) { + log.debug("Starting " + this.getClass().getCanonicalName()); + } + flowmodList = new ArrayList<String>(); + flowmods = new HashMap<Long, HashMap<String, OFFlowMod>>(); + activeSwitches = new ArrayList<IOFSwitch>(); floodlightProvider.addOFSwitchListener(this); pushEntriesTimer = new Runnable() { @Override @@ -622,21 +676,4 @@ public class StaticFlowEntryPusher implements IStaticFlowEntryPusherService, IOF // Initially push entries in 1 second floodlightProvider.getScheduledExecutor().schedule(pushEntriesTimer, 1, TimeUnit.SECONDS); } - - /** - * Pushes all entries associated with all switches (from the store) - */ - protected void pushAllEntries() { - for (IOFSwitch sw : activeSwitches) { - for (OFFlowMod fm : getEntries(sw).values()) { - pushEntry(sw, fm); - } - } - } - - public void shutDown() { - log.info("shutdown"); - pushEntriesTimer = null; - floodlightProvider.removeOFSwitchListener(this); - } } diff --git a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java index cdf1ac238..b07f105d4 100644 --- a/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java +++ b/src/main/java/net/floodlightcontroller/storage/AbstractStorageSource.java @@ -27,10 +27,15 @@ import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; + +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.IFloodlightModule; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public abstract class AbstractStorageSource implements IStorageSourceService { +public abstract class AbstractStorageSource + implements IStorageSourceService, IFloodlightModule { protected static Logger logger = LoggerFactory.getLogger(AbstractStorageSource.class); // Shared instance of the executor to use to execute the storage tasks. @@ -83,12 +88,6 @@ public abstract class AbstractStorageSource implements IStorageSourceService { this.executorService = defaultExecutorService; } - public AbstractStorageSource(ExecutorService executorService, - IStorageExceptionHandler exceptionHandler) { - setExecutorService(executorService); - this.exceptionHandler = exceptionHandler; - } - public void setExecutorService(ExecutorService executorService) { this.executorService = (executorService != null) ? executorService : defaultExecutorService; @@ -330,4 +329,9 @@ public abstract class AbstractStorageSource implements IStorageSourceService { notifyListeners(notification); } + @Override + public void startUp(FloodlightModuleContext context) { + // TODO Auto-generated method stub + + } } diff --git a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java index d4c1ca417..ae0ae9e7a 100644 --- a/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java +++ b/src/main/java/net/floodlightcontroller/storage/memory/MemoryStorageSource.java @@ -17,8 +17,12 @@ package net.floodlightcontroller.storage.memory; +import net.floodlightcontroller.core.IFloodlightService; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; import net.floodlightcontroller.perfmon.PktinProcessingTime; import net.floodlightcontroller.storage.nosql.NoSqlStorageSource; +import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.SynchronousExecutorService; import java.util.ArrayList; @@ -33,13 +37,8 @@ import net.floodlightcontroller.storage.StorageException; public class MemoryStorageSource extends NoSqlStorageSource { private Map<String, MemoryTable> tableMap = new HashMap<String,MemoryTable>(); - PktinProcessingTime pktinProcessingTime; - public MemoryStorageSource() { - super(new SynchronousExecutorService(), null); - } - synchronized private MemoryTable getTable(String tableName, boolean create) { MemoryTable table = tableMap.get(tableName); if (table == null) { @@ -177,4 +176,42 @@ public class MemoryStorageSource extends NoSqlStorageSource { PktinProcessingTime pktinProcessingTime) { this.pktinProcessingTime = pktinProcessingTime; } + + // IFloodlightModule methods + + @Override + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IStorageSourceService.class); + return l; + } + + @Override + public Map<Class<? extends IFloodlightService>, + IFloodlightService> getServiceImpls() { + Map<Class<? extends IFloodlightService>, + IFloodlightService> m = + new HashMap<Class<? extends IFloodlightService>, + IFloodlightService>(); + m.put(IStorageSourceService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + // we don't have any depedencies + return null; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + // no-op + } + + @Override + public void startUp(FloodlightModuleContext context) { + executorService = new SynchronousExecutorService(); + } } diff --git a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java index c3a691a4e..284354ec9 100644 --- a/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java +++ b/src/main/java/net/floodlightcontroller/storage/nosql/NoSqlStorageSource.java @@ -33,7 +33,6 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TimeZone; -import java.util.concurrent.ExecutorService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -43,7 +42,6 @@ import net.floodlightcontroller.storage.CompoundPredicate; import net.floodlightcontroller.storage.IPredicate; import net.floodlightcontroller.storage.IQuery; import net.floodlightcontroller.storage.IResultSet; -import net.floodlightcontroller.storage.IStorageExceptionHandler; import net.floodlightcontroller.storage.OperatorPredicate; import net.floodlightcontroller.storage.RowOrdering; import net.floodlightcontroller.storage.StorageException; @@ -525,11 +523,6 @@ public abstract class NoSqlStorageSource extends AbstractStorageSource { super(); } - public NoSqlStorageSource(ExecutorService executorService, - IStorageExceptionHandler exceptionHandler) { - super(executorService, exceptionHandler); - } - @Override public void createTable(String tableName, Set<String> indexedColumns) { if (indexedColumns == null) return; diff --git a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java index c8dd10e8e..1ac0faa68 100644 --- a/src/main/java/net/floodlightcontroller/topology/ITopologyService.java +++ b/src/main/java/net/floodlightcontroller/topology/ITopologyService.java @@ -86,6 +86,9 @@ public interface ITopologyService extends IFloodlightService { */ public Map<IOFSwitch, Set<LinkTuple>> getSwitchLinks(); - // gets called in startup method - public void addTopologyListener(ITopologyListener listener); + /** + * Adds a listener to listen for ITopologyService messages + * @param listener The listener that wants the notifications + */ + public void addListener(ITopologyListener listener); } diff --git a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java index 19c1015a2..49fa69cee 100644 --- a/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java +++ b/src/main/java/net/floodlightcontroller/topology/internal/TopologyImpl.java @@ -20,6 +20,7 @@ package net.floodlightcontroller.topology.internal; import java.io.IOException; import java.nio.ByteBuffer; import java.util.ArrayList; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; @@ -34,17 +35,21 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; +import net.floodlightcontroller.core.IFloodlightService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchListener; +import net.floodlightcontroller.core.module.FloodlightModuleContext; +import net.floodlightcontroller.core.module.FloodlightModuleException; +import net.floodlightcontroller.core.module.IFloodlightModule; import net.floodlightcontroller.core.util.SingletonTask; import net.floodlightcontroller.packet.BPDU; import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.LLDP; import net.floodlightcontroller.packet.LLDPTLV; import net.floodlightcontroller.routing.BroadcastTree; -import net.floodlightcontroller.routing.IRoutingEngine; +import net.floodlightcontroller.routing.IRoutingEngineService; import net.floodlightcontroller.storage.IResultSet; import net.floodlightcontroller.storage.IStorageSourceService; import net.floodlightcontroller.storage.IStorageSourceListener; @@ -97,8 +102,10 @@ import org.slf4j.LoggerFactory; * * @author David Erickson (daviderickson@cs.stanford.edu) */ -public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, - IStorageSourceListener, ITopologyService { +public class TopologyImpl + implements IOFMessageListener, IOFSwitchListener, + IStorageSourceListener, ITopologyService, + IFloodlightModule { protected static Logger log = LoggerFactory.getLogger(TopologyImpl.class); // Names of table/fields for links in the storage API @@ -115,9 +122,9 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, private static final String SWITCH_TABLE_NAME = "controller_switch"; private static final String SWITCH_CORE_SWITCH = "core_switch"; - protected IFloodlightProvider floodlightProvider; + protected IFloodlightProviderService floodlightProvider; protected IStorageSourceService storageSource; - protected IRoutingEngine routingEngine; + protected IRoutingEngineService routingEngine; /** * Map from link to the most recent time it was verified functioning @@ -213,15 +220,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } } - public TopologyImpl() { - this.lock = new ReentrantReadWriteLock(); - this.updates = new LinkedBlockingQueue<Update>(); - this.links = new HashMap<LinkTuple, LinkInfo>(); - this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>(); - this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>(); - - } - private void doUpdatesThread() throws InterruptedException { do { Update update = updates.take(); @@ -263,88 +261,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, detectLoop(); } - public void startUp() { - floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); - floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this); - floodlightProvider.addOFSwitchListener(this); - - ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor(); - - Runnable lldpSendTimer = new Runnable() { - @Override - public void run() { - try { - sendLLDPs(); - - if (!shuttingDown) { - ScheduledExecutorService ses = - floodlightProvider.getScheduledExecutor(); - ses.schedule(this, lldpFrequency, - TimeUnit.MILLISECONDS); - } - } catch (StorageException e) { - log.error("Storage exception in LLDP send timer; " + - "terminating process", e); - floodlightProvider.terminate(); - } catch (Exception e) { - log.error("Exception in LLDP send timer", e); - } - } - }; - ses.schedule(lldpSendTimer, 1000, TimeUnit.MILLISECONDS); - - Runnable timeoutLinksTimer = new Runnable() { - @Override - public void run() { - log.trace("Running timeoutLinksTimer"); - try { - timeoutLinks(); - if (!shuttingDown) { - ScheduledExecutorService ses = - floodlightProvider.getScheduledExecutor(); - ses.schedule(this, lldpTimeout, TimeUnit.MILLISECONDS); - } - } catch (StorageException e) { - log.error("Storage exception in link timer; " + - "terminating process", e); - floodlightProvider.terminate(); - } catch (Exception e) { - log.error("Exception in timeoutLinksTimer", e); - } - } - }; - ses.schedule(timeoutLinksTimer, 1000, TimeUnit.MILLISECONDS); - - updatesThread = new Thread(new Runnable () { - @Override - public void run() { - while (true) { - try { - doUpdatesThread(); - } catch (InterruptedException e) { - return; - } - } - }}, "Topology Updates"); - updatesThread.start(); - - try { - storageSource.addListener(SWITCH_TABLE_NAME, this); - } - catch (StorageException ex) { - log.error("Error in installing listener for switch table - {}", SWITCH_TABLE_NAME); - // floodlightProvider.terminate(); // For now, log this error and continue - } - } - - protected void shutDown() { - shuttingDown = true; - floodlightProvider.removeOFSwitchListener(this); - floodlightProvider.removeOFMessageListener(OFType.PACKET_IN, this); - floodlightProvider.removeOFMessageListener(OFType.PORT_STATUS, this); - updatesThread.interrupt(); - } - /** * Detect loops in the openflow clusters and construct spanning trees * for broadcast @@ -527,7 +443,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, } } - // TODO get rid of this @Override public String getName() { return "topology"; @@ -612,8 +527,8 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, protected Command handlePacketIn(IOFSwitch sw, OFPacketIn pi, FloodlightContext cntx) { Ethernet eth = - IFloodlightProvider.bcStore.get(cntx, - IFloodlightProvider.CONTEXT_PI_PAYLOAD); + IFloodlightProviderService.bcStore.get(cntx, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD); if (eth.getPayload() instanceof LLDP) return handleLldp((LLDP) eth.getPayload(), sw, pi); @@ -929,14 +844,6 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, return true; } - /** - * Sets the IFloodlightProvider for this TopologyImpl. - * @param floodlightProvider the floodlightProvider to set - */ - public void setFloodlightProvider(IFloodlightProvider floodlightProvider) { - this.floodlightProvider = floodlightProvider; - } - /** * Checks to see if a SwitchPortTuple is internal. A SwitchPortTuple is * defined as internal if the switch is a core switch if only switches that @@ -1366,39 +1273,9 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, storageSource.deleteRowAsync(LINK_TABLE_NAME, id); } - /** - * @param topologyAware the topologyAware to set - */ - public void setTopologyAware(Set<ITopologyListener> topologyAware) { - // TODO make this a copy on write set or lock it somehow - this.topologyAware = topologyAware; - } - - /** - * Sets the IStorageSource to use for ITology - * @param storageSource the storage source to use - */ - public void setStorageSource(IStorageSourceService storageSource) { - this.storageSource = storageSource; - storageSource.createTable(LINK_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID); - } - - /** - * Gets the storage source for this ITopology - * @return The IStorageSource ITopology is writing to - */ - public IStorageSourceService getStorageSource() { - return storageSource; - } - - /** - * @param storageSource the storage source to use for persisting link info - */ - public void setRoutingEngine(IRoutingEngine routingEngine) { - this.routingEngine = routingEngine; - storageSource.createTable(LINK_TABLE_NAME, null); - storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID); + @Override + public void addListener(ITopologyListener listener) { + topologyAware.add(listener); } @Override @@ -1467,9 +1344,138 @@ public class TopologyImpl implements IOFMessageListener, IOFSwitchListener, // Ignore delete events, the switch delete will do the right thing on it's own } + // IFloodlightModule classes + @Override - public void addTopologyListener(ITopologyListener listener) { - // TODO Auto-generated method stub + public Collection<Class<? extends IFloodlightService>> getServices() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(ITopologyService.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(ITopologyService.class, this); + return m; + } + + @Override + public Collection<Class<? extends IFloodlightService>> getDependencies() { + Collection<Class<? extends IFloodlightService>> l = + new ArrayList<Class<? extends IFloodlightService>>(); + l.add(IFloodlightProviderService.class); + l.add(IStorageSourceService.class); + l.add(IRoutingEngineService.class); + return l; + } + + @Override + public void init(FloodlightModuleContext context) + throws FloodlightModuleException { + floodlightProvider = context.getServiceImpl(IFloodlightProviderService.class); + storageSource = context.getServiceImpl(IStorageSourceService.class); + routingEngine = context.getServiceImpl(IRoutingEngineService.class); + + // We create this here because there is no ordering guarantee + this.topologyAware = new HashSet<ITopologyListener>(); + } + + @Override + public void startUp(FloodlightModuleContext context) { + // Our 'constructor' + + // Setup our data structures + this.lock = new ReentrantReadWriteLock(); + this.updates = new LinkedBlockingQueue<Update>(); + this.links = new HashMap<LinkTuple, LinkInfo>(); + this.portLinks = new HashMap<SwitchPortTuple, Set<LinkTuple>>(); + this.switchLinks = new HashMap<IOFSwitch, Set<LinkTuple>>(); + + // Create our storage tables + storageSource.createTable(LINK_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID); + storageSource.createTable(LINK_TABLE_NAME, null); + storageSource.setTablePrimaryKeyName(LINK_TABLE_NAME, LINK_ID); + // Register for storage updates for the switch table + try { + storageSource.addListener(SWITCH_TABLE_NAME, this); + } catch (StorageException ex) { + log.error("Error in installing listener for switch table - {}", SWITCH_TABLE_NAME); + } + + + ScheduledExecutorService ses = floodlightProvider.getScheduledExecutor(); + + // Setup sending out LLDPs + Runnable lldpSendTimer = new Runnable() { + @Override + public void run() { + try { + sendLLDPs(); + + if (!shuttingDown) { + ScheduledExecutorService ses = + floodlightProvider.getScheduledExecutor(); + ses.schedule(this, lldpFrequency, + TimeUnit.MILLISECONDS); + } + } catch (StorageException e) { + log.error("Storage exception in LLDP send timer; " + + "terminating process", e); + floodlightProvider.terminate(); + } catch (Exception e) { + log.error("Exception in LLDP send timer", e); + } + } + }; + ses.schedule(lldpSendTimer, 1000, TimeUnit.MILLISECONDS); + + Runnable timeoutLinksTimer = new Runnable() { + @Override + public void run() { + log.trace("Running timeoutLinksTimer"); + try { + timeoutLinks(); + if (!shuttingDown) { + ScheduledExecutorService ses = + floodlightProvider.getScheduledExecutor(); + ses.schedule(this, lldpTimeout, TimeUnit.MILLISECONDS); + } + } catch (StorageException e) { + log.error("Storage exception in link timer; " + + "terminating process", e); + floodlightProvider.terminate(); + } catch (Exception e) { + log.error("Exception in timeoutLinksTimer", e); + } + } + }; + ses.schedule(timeoutLinksTimer, 1000, TimeUnit.MILLISECONDS); + + updatesThread = new Thread(new Runnable () { + @Override + public void run() { + while (true) { + try { + doUpdatesThread(); + } catch (InterruptedException e) { + return; + } + } + }}, "Topology Updates"); + updatesThread.start(); + // Register for the OpenFlow messages we want to receive + floodlightProvider.addOFMessageListener(OFType.PACKET_IN, this); + floodlightProvider.addOFMessageListener(OFType.PORT_STATUS, this); + // Register for switch updates + floodlightProvider.addOFSwitchListener(this); } } diff --git a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java index 17993d3ad..2ca28981f 100644 --- a/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java +++ b/src/test/java/net/floodlightcontroller/core/internal/ControllerTest.java @@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantReadWriteLock; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFMessageListener.Command; import net.floodlightcontroller.core.IOFSwitch; @@ -354,7 +354,7 @@ public class ControllerTest extends FloodlightTestCase { .setLengthU(OFPacketOut.MINIMUM_LENGTH+packetOut.getActionsLength()+testPacketSerialized.length); FloodlightContext cntx = new FloodlightContext(); - IFloodlightProvider.bcStore.put(cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD, (Ethernet) testPacket); + IFloodlightProviderService.bcStore.put(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, (Ethernet) testPacket); // Let's check the listeners. diff --git a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java index 9758c6a08..2c6e86c43 100644 --- a/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java +++ b/src/test/java/net/floodlightcontroller/core/test/MockFloodlightProvider.java @@ -26,7 +26,7 @@ import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.ScheduledExecutorService; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFMessageListener; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.IOFSwitchFilter; @@ -43,7 +43,7 @@ import org.openflow.protocol.factory.BasicFactory; * * @author David Erickson (daviderickson@cs.stanford.edu) */ -public class MockFloodlightProvider implements IFloodlightProvider { +public class MockFloodlightProvider implements IFloodlightProviderService { protected Map<OFType, List<IOFMessageListener>> listeners; protected List<IOFSwitchListener> switchListeners; protected Map<Long, IOFSwitch> switches; @@ -123,8 +123,8 @@ public class MockFloodlightProvider implements IFloodlightProvider { OFPacketIn pi = (OFPacketIn)msg; Ethernet eth = new Ethernet(); eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length); - IFloodlightProvider.bcStore.put(bc, - IFloodlightProvider.CONTEXT_PI_PAYLOAD, + IFloodlightProviderService.bcStore.put(bc, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } while (it.hasNext() && !Command.STOP.equals(result)) { diff --git a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java index c4d98c2aa..f8aacabe0 100644 --- a/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java +++ b/src/test/java/net/floodlightcontroller/devicemanager/internal/DeviceManagerImplTest.java @@ -68,7 +68,7 @@ public class DeviceManagerImplTest extends FloodlightTestCase { deviceManager = new DeviceManagerImpl(); deviceManager.setFloodlightProvider(mockFloodlightProvider); deviceManager.setStorageSource(new MemoryStorageSource()); - deviceManager.startUp(); + //deviceManager.startUp(); // Build our test packet this.testPacket = new Ethernet() diff --git a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java index d657e1035..28dcbe70b 100644 --- a/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java +++ b/src/test/java/net/floodlightcontroller/forwarding/ForwardingTest.java @@ -32,7 +32,7 @@ import java.util.List; import java.util.Map; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.IOFSwitch; import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.devicemanager.Device; @@ -42,7 +42,7 @@ import net.floodlightcontroller.packet.Ethernet; import net.floodlightcontroller.packet.IPacket; import net.floodlightcontroller.packet.IPv4; import net.floodlightcontroller.packet.UDP; -import net.floodlightcontroller.routing.IRoutingEngine; +import net.floodlightcontroller.routing.IRoutingEngineService; import net.floodlightcontroller.routing.Link; import net.floodlightcontroller.routing.Route; import net.floodlightcontroller.test.FloodlightTestCase; @@ -68,7 +68,7 @@ public class ForwardingTest extends FloodlightTestCase { protected MockFloodlightProvider mockFloodlightProvider; protected FloodlightContext cntx; protected IDeviceManagerService deviceManager; - protected IRoutingEngine routingEngine; + protected IRoutingEngineService routingEngine; protected Forwarding forwarding; protected ITopologyService topology; protected IOFSwitch sw1, sw2; @@ -89,7 +89,7 @@ public class ForwardingTest extends FloodlightTestCase { mockFloodlightProvider = getMockFloodlightProvider(); forwarding = getForwarding(); deviceManager = createMock(IDeviceManagerService.class); - routingEngine = createMock(IRoutingEngine.class); + routingEngine = createMock(IRoutingEngineService.class); topology = createMock(ITopologyService.class); forwarding.setFloodlightProvider(mockFloodlightProvider); forwarding.setDeviceManager(deviceManager); @@ -183,7 +183,7 @@ public class ForwardingTest extends FloodlightTestCase { expected_wildcards &= ~OFMatch.OFPFW_NW_SRC_MASK & ~OFMatch.OFPFW_NW_DST_MASK; // Add the packet to the context store - IFloodlightProvider.bcStore.put(cntx, IFloodlightProvider.CONTEXT_PI_PAYLOAD, (Ethernet)testPacket); + IFloodlightProviderService.bcStore.put(cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD, (Ethernet)testPacket); } private Forwarding getForwarding() { diff --git a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java index 944443884..addc9e555 100644 --- a/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java +++ b/src/test/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusherTest.java @@ -66,9 +66,9 @@ public class StaticFlowEntryPusherTest extends FloodlightTestCase { Map<Long, IOFSwitch> switchMap = new HashMap<Long, IOFSwitch>(); switchMap.put(dpid, mockSwitch); mockFloodlightProvider.setSwitches(switchMap); - staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider); + //staticFlowEntryPusher.setFloodlightProvider(mockFloodlightProvider); long timeSfpStart = System.currentTimeMillis(); - staticFlowEntryPusher.startUp(); + //staticFlowEntryPusher.startUp(); // if someone calls getId(), return this dpid instead expect(mockSwitch.getId()).andReturn(dpid).anyTimes(); diff --git a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java index 46a0ede97..23d649a93 100644 --- a/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java +++ b/src/test/java/net/floodlightcontroller/test/FloodlightTestCase.java @@ -19,7 +19,7 @@ package net.floodlightcontroller.test; import junit.framework.TestCase; import net.floodlightcontroller.core.FloodlightContext; -import net.floodlightcontroller.core.IFloodlightProvider; +import net.floodlightcontroller.core.IFloodlightProviderService; import net.floodlightcontroller.core.test.MockFloodlightProvider; import net.floodlightcontroller.packet.Ethernet; @@ -56,8 +56,8 @@ public class FloodlightTestCase extends TestCase { OFPacketIn pi = (OFPacketIn)m; Ethernet eth = new Ethernet(); eth.deserialize(pi.getPacketData(), 0, pi.getPacketData().length); - IFloodlightProvider.bcStore.put(bc, - IFloodlightProvider.CONTEXT_PI_PAYLOAD, + IFloodlightProviderService.bcStore.put(bc, + IFloodlightProviderService.CONTEXT_PI_PAYLOAD, eth); } return bc; -- GitLab