X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FInventoryService.java;fp=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FInventoryService.java;h=7041f447e37608b15f9321f6e2ac82d56520f137;hb=29f7cfb54b580928c7feac63abce028a7014b0d5;hp=0000000000000000000000000000000000000000;hpb=42210c03b0a4c54706320ba9f55794c0abd4d201;p=controller.git diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryService.java new file mode 100644 index 0000000000..7041f447e3 --- /dev/null +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryService.java @@ -0,0 +1,345 @@ + +/* + * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.controller.protocol_plugin.openflow.internal; + +import java.util.Collections; +import java.util.Date; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.felix.dm.Component; +import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener; +import org.opendaylight.controller.protocol_plugin.openflow.IOFInventoryService; +import org.opendaylight.controller.protocol_plugin.openflow.core.IController; +import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.opendaylight.controller.sal.core.ConstructionException; +import org.opendaylight.controller.sal.core.Node; +import org.opendaylight.controller.sal.core.Node.NodeIDType; +import org.opendaylight.controller.sal.core.NodeConnector; +import org.opendaylight.controller.sal.core.Property; +import org.opendaylight.controller.sal.core.TimeStamp; +import org.opendaylight.controller.sal.core.Tables; +import org.opendaylight.controller.sal.core.Actions; +import org.opendaylight.controller.sal.core.Buffers; +import org.opendaylight.controller.sal.core.Capabilities; +import org.opendaylight.controller.sal.core.UpdateType; +import org.opendaylight.controller.sal.inventory.IPluginInInventoryService; +import org.opendaylight.controller.sal.inventory.IPluginOutInventoryService; +import org.opendaylight.controller.sal.utils.GlobalConstants; + +/** + * The class describes inventory service protocol plugin. One instance per + * container of the network. Each instance gets container specific inventory + * events from InventoryServiceShim. It interacts with SAL to pass inventory + * data to the upper application. + * + * + */ +public class InventoryService implements IInventoryShimInternalListener, + IPluginInInventoryService, IOFInventoryService { + protected static final Logger logger = LoggerFactory + .getLogger(InventoryService.class); + private Set pluginOutInventoryServices = Collections + .synchronizedSet(new HashSet()); + private IController controller = null; + private ConcurrentMap> nodeProps; // properties are maintained in default container only + private ConcurrentMap> nodeConnectorProps; // properties are maintained in default container only + private boolean isDefaultContainer = false; + + void setController(IController s) { + this.controller = s; + } + + void unsetController(IController s) { + if (this.controller == s) { + this.controller = null; + } + } + + /** + * Function called by the dependency manager when all the required + * dependencies are satisfied + * + */ + @SuppressWarnings("rawtypes") + void init(Component c) { + logger.trace("INIT called!"); + + Dictionary props = c.getServiceProperties(); + if (props != null) { + String containerName = (String) props.get("containerName"); + isDefaultContainer = containerName.equals(GlobalConstants.DEFAULT + .toString()); + } + + nodeProps = new ConcurrentHashMap>(); + nodeConnectorProps = new ConcurrentHashMap>(); + } + + /** + * 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.trace("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.trace("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.trace("STOP called!"); + } + + public void setPluginOutInventoryServices(IPluginOutInventoryService service) { + logger.trace("Got a service set request {}", service); + if (this.pluginOutInventoryServices != null) { + this.pluginOutInventoryServices.add(service); + } + } + + public void unsetPluginOutInventoryServices( + IPluginOutInventoryService service) { + logger.trace("Got a service UNset request"); + if (this.pluginOutInventoryServices != null) { + this.pluginOutInventoryServices.remove(service); + } + } + + protected Node OFSwitchToNode(ISwitch sw) { + Node node = null; + Object id = sw.getId(); + + try { + node = new Node(NodeIDType.OPENFLOW, id); + } catch (ConstructionException e) { + e.printStackTrace(); + } + + return node; + } + + /** + * Retrieve nodes from openflow + */ + @Override + public ConcurrentMap> getNodeProps() { + if (nodeProps == null) + return null; + Map switches = controller.getSwitches(); + for (Map.Entry entry : switches.entrySet()) { + ISwitch sw = entry.getValue(); + Node node = OFSwitchToNode(sw); + Map propMap = null; + if (isDefaultContainer) { + propMap = new HashMap(); + byte tables = sw.getTables(); + Tables t = new Tables(tables); + if (t != null) { + propMap.put(Tables.TablesPropName,t); + } + int cap = sw.getCapabilities(); + Capabilities c = new Capabilities(cap); + if (c != null) { + propMap.put(Capabilities.CapabilitiesPropName, c); + } + int act = sw.getActions(); + Actions a = new Actions(act); + if (a != null) { + propMap.put(Actions.ActionsPropName,a); + } + int buffers = sw.getBuffers(); + Buffers b = new Buffers(buffers); + if (b != null) { + propMap.put(Buffers.BuffersPropName,b); + } + Date connectedSince = sw.getConnectedDate(); + Long connectedSinceTime = (connectedSince == null) ? 0 + : connectedSince.getTime(); + TimeStamp timeStamp = new TimeStamp(connectedSinceTime, + "connectedSince"); + propMap.put(TimeStamp.TimeStampPropName, timeStamp); + nodeProps.put(node, propMap); + } + } + return nodeProps; + } + + @Override + public ConcurrentMap> getNodeConnectorProps( + Boolean refresh) { + if (nodeConnectorProps == null) + return null; + + if (isDefaultContainer && refresh) { + Map switches = controller.getSwitches(); + for (ISwitch sw : switches.values()) { + Map> ncProps = InventoryServiceHelper + .OFSwitchToProps(sw); + for (Map.Entry> entry : ncProps + .entrySet()) { + updateNodeConnector(entry.getKey(), UpdateType.ADDED, entry + .getValue()); + } + } + } + + return nodeConnectorProps; + } + + @Override + public void updateNodeConnector(NodeConnector nodeConnector, + UpdateType type, Set props) { + logger.trace("NodeConnector id " + nodeConnector.getID() + + " type " + nodeConnector.getType() + " " + + type.getName() + " for Node id " + + nodeConnector.getNode().getID()); + + if (nodeConnectorProps == null) + return; + + synchronized (nodeConnectorProps) { + Map propMap = nodeConnectorProps + .get(nodeConnector); + switch (type) { + case ADDED: + case CHANGED: + if (propMap == null) + propMap = new HashMap(); + + if (props != null) { + for (Property prop : props) { + propMap.put(prop.getName(), prop); + } + } + nodeConnectorProps.put(nodeConnector, propMap); + break; + case REMOVED: + nodeConnectorProps.remove(nodeConnector); + break; + default: + return; + } + } + + // update sal and discovery + synchronized (pluginOutInventoryServices) { + for (IPluginOutInventoryService service : pluginOutInventoryServices) { + service.updateNodeConnector(nodeConnector, type, props); + } + } + } + + private void addNode(Node node, Set props) { + logger.trace("{} added", node); + if (nodeProps == null) + return; + + // update local cache + Map propMap = new HashMap(); + for (Property prop : props) { + propMap.put(prop.getName(), prop); + } + nodeProps.put(node, propMap); + + // update sal + synchronized (pluginOutInventoryServices) { + for (IPluginOutInventoryService service : pluginOutInventoryServices) { + service.updateNode(node, UpdateType.ADDED, props); + } + } + } + + private void removeNode(Node node) { + logger.trace("{} removed", node); + if (nodeProps == null) + return; + + // update local cache + nodeProps.remove(node); + + Set removeSet = new HashSet(); + for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) { + if (nodeConnector.getNode().equals(node)) { + removeSet.add(nodeConnector); + } + } + for (NodeConnector nodeConnector : removeSet) { + nodeConnectorProps.remove(nodeConnector); + } + + // update sal + synchronized (pluginOutInventoryServices) { + for (IPluginOutInventoryService service : pluginOutInventoryServices) { + service.updateNode(node, UpdateType.REMOVED, null); + } + } + } + + /* + * Function called by other protocol plugin modules to notify Inventory Service + * that a property has changed for the specified switch + */ + @Override + public void updateSwitchProperty(Long switchId, Set propSet) { + // update local cache + Node node = OFSwitchToNode(controller.getSwitches().get(switchId)); + Map propMap = nodeProps.get(node); + if (propMap == null) + propMap = new HashMap(); + for (Property prop : propSet) { + propMap.put(prop.getName(), prop); + } + nodeProps.put(node, propMap); + + // update sal + synchronized (pluginOutInventoryServices) { + for (IPluginOutInventoryService service : pluginOutInventoryServices) { + service.updateNode(node, UpdateType.CHANGED, propSet); + } + } + } + + @Override + public void updateNode(Node node, UpdateType type, Set props) { + switch (type) { + case ADDED: + addNode(node, props); + break; + case REMOVED: + removeNode(node); + break; + default: + break; + } + } +}