/* ONF SampleTap Software License Copyright ©2014 Open Networking Foundation This ONF SampleTap software is licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the original license at http://www.apache.org/licenses/LICENSE-2.0 and also in the main directory of the source distribution. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. End of ONF SampleTap Software License */ package org.opendaylight.controller.samples.onftappingapp.internal; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager; import org.opendaylight.controller.hosttracker.IfNewHostNotify; import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; import org.opendaylight.controller.sal.core.Property; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.statisticsmanager.IStatisticsManager; import org.opendaylight.controller.switchmanager.IInventoryListener; import org.opendaylight.controller.switchmanager.ISwitchManager; import org.opendaylight.controller.switchmanager.Switch; import org.opendaylight.controller.switchmanager.SwitchConfig; import org.opendaylight.controller.samples.onftappingapp.DBAuthenticationException; import org.opendaylight.controller.samples.onftappingapp.DatabaseConnectException; import org.opendaylight.controller.samples.onftappingapp.TappingApp; /** * This class implements port tapping for hosts connected to the managed devices. * <br/> * The work flow is as follows: * This module listens for new switch nodes from the * {@link org.opendaylight.controller.switchmanager.IInventoryListener } * service and on discovering a new switch it adds flow rules based on the config */ public class ONFTappingAppImpl implements IfNewHostNotify, IInventoryListener { private static Logger logger = LoggerFactory.getLogger(ONFTappingAppImpl.class); // Our TappingApp TappingApp tappingApp = null; // Web-server for TappingAPp GUI Router router = null; // SwitchManager from ODL. Used to configure switches and obtain their properties protected ISwitchManager switchManager = null; // Forwarding Rules Manager private IForwardingRulesManager forwardingRulesManager = null; // Statistics Manager private IStatisticsManager statisticsManager = null; // Function called when the plugin gets activated public void startUp() { logger.info("ONFTappingApp start up"); logger.info("Application directory is " + System.getProperty("user.dir")); try { // Construct an instance of the TappingApp tappingApp = new TappingApp("ONS Tapping App", "localhost", this); // Construct an instance of the webs-server for the GUI router = new Router(tappingApp); } catch (DBAuthenticationException authException) { logger.error("Unable to connect to database " + authException.toString()); authException.printStackTrace(); } catch (DatabaseConnectException dbException) { logger.error("Unable to connect to database " + dbException.toString()); dbException.printStackTrace(); } } // Function called when the plugin is stopped public void shutDown() { logger.info("ONFTappingApp shutdown"); logger.info("Destroy all the switch Rules"); } public void setSwitchManager(ISwitchManager switchManager) { this.switchManager = switchManager; } public ISwitchManager getSwitchManager() { return this.switchManager; } public void unsetSwitchManager(ISwitchManager switchManager) { if (this.switchManager == switchManager) { this.switchManager = null; } } public void setForwardingRulesManager(IForwardingRulesManager forwardingRulesManager) { logger.debug("Setting ForwardingRulesManager"); this.forwardingRulesManager = forwardingRulesManager; } public void unsetForwardingRulesManager(IForwardingRulesManager forwardingRulesManager) { if (this.forwardingRulesManager == forwardingRulesManager) { this.forwardingRulesManager = null; } } public IForwardingRulesManager getForwardingRulesManager() { return forwardingRulesManager; } public IStatisticsManager getStatisticsManager() { return statisticsManager; } public void setStatisticsManager(IStatisticsManager statisticsManager) { this.statisticsManager = statisticsManager; } @Override public void notifyHTClient(HostNodeConnector arg0) { logger.info("notifyHTClient ignored"); } @Override public void notifyHTClientHostRemoved(HostNodeConnector arg0) { logger.info("notifyHTClientHostRemoved ignored"); } @Override public void notifyNode(Node node, UpdateType type, Map<String, Property> propMap) { logger.info("notifyNode: Type " + type); if (node == null) { logger.info("Node is null "); return; } // We only support OpenFlow switches for now if (!node.getType().equals(Node.NodeIDType.OPENFLOW)) { logger.debug("OpenFlow node {} added. Initialize flows", node); return; } // Delegate the processing to the tappingApp tappingApp.switchChanged(type, node); } // Print all we can find out about a node private void logNodeInfo(Node node, Map<String, Property> propMap) { logger.info("logNodeInfo Node {} added ", node); SwitchConfig config = this.switchManager.getSwitchConfig(node.getNodeIDString()); logger.info("Config " + config); Map<String,Property> nodeProps = this.switchManager.getNodeProps(node); logger.info("NodeProperties " + nodeProps); // Get the set of NodeConnectors for the Node (ie. the set of switch ports for the switch) Set<NodeConnector> switchPorts = switchManager.getNodeConnectors(node); for (NodeConnector switchPort : switchPorts) { Map<String, Property> ncprop = switchManager.getNodeConnectorProps(switchPort); logger.info("NC props " + ncprop); } logger.info("Node {} ID {}", node, node.getNodeIDString()); if (propMap != null) logger.info("Properties " + propMap); List<Switch> switches = this.switchManager.getNetworkDevices(); logger.info("Switches " + switches); List<Switch> networkDevs = switchManager.getNetworkDevices(); if (networkDevs == null) { logger.debug("No OF nodes learned yet in {}", node); } else { logger.info("Number of net dev nodes " + networkDevs.size()); for (Switch netDevNode : networkDevs) { logger.info("Network Dev Node: " + netDevNode); } } logger.info("Controller props " + switchManager.getControllerProperties()); Set<Node> nodes = switchManager.getNodes(); logger.info("Nodes " + nodes); Iterator<Node> nit = nodes.iterator(); while (nit.hasNext()) { logger.info("Node: " + nit.next()); } } @Override public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) { logger.info("notifyNodeConnector"); if (nodeConnector == null) { logger.info("NodeConnector is null"); return; } Node node = nodeConnector.getNode(); this.logNodeInfo(node, propMap); switch (type) { case ADDED: logger.info("NodeConnector {} added ", nodeConnector); break; case CHANGED: logger.info("NodeConnector {} changed ", nodeConnector); break; case REMOVED: logger.info("NodeConnector {} removed, doing a cleanup", nodeConnector); break; default: logger.info("Unknown type received " + type); break; } } // Function called by the dependency manager when all the required // dependencies are satisfied void init() { logger.info("init called"); startUp(); } // Function called by the dependency manager when at least one // dependency become unsatisfied or when the component is shutting // down because for example bundle is being stopped. void destroy() { logger.info("destroy called"); } // Function called by dependency manager after "init ()" is called // and after the services provided by the class are registered in //the service registry void start() { logger.info("start called"); } // Function called by the dependency manager before the services // exported by the component are unregistered, this will be // followed by a "destroy ()" calls void stop() { logger.info("start called"); } }