X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fprotocol_plugins%2Fopenflow%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fprotocol_plugin%2Fopenflow%2Finternal%2FReadServiceFilter.java;h=7f9a13e92ac3be846342a7615e37ec658d8b9fa0;hp=22e8a4dc74eb897847c0d2835f9060f3f506ea01;hb=1f46115777f3dfe4ed653ea2c06cd3fe637fb122;hpb=541d0a36997f292bb037a2199463431eee538358 diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/ReadServiceFilter.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/ReadServiceFilter.java index 22e8a4dc74..7f9a13e92a 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/ReadServiceFilter.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/ReadServiceFilter.java @@ -10,22 +10,20 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsListener; import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsManager; -import org.opendaylight.controller.protocol_plugin.openflow.IPluginReadServiceFilter; +import org.opendaylight.controller.protocol_plugin.openflow.IReadFilterInternalListener; +import org.opendaylight.controller.protocol_plugin.openflow.IReadServiceFilter; import org.opendaylight.controller.protocol_plugin.openflow.core.IController; -import org.openflow.protocol.OFMatch; -import org.openflow.protocol.statistics.OFPortStatisticsReply; -import org.openflow.protocol.statistics.OFStatistics; -import org.openflow.protocol.statistics.OFStatisticsType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; import org.opendaylight.controller.sal.action.Output; @@ -46,7 +44,14 @@ import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.NodeCreator; import org.opendaylight.controller.sal.utils.NodeTableCreator; +import org.openflow.protocol.OFMatch; +import org.openflow.protocol.statistics.OFFlowStatisticsReply; +import org.openflow.protocol.statistics.OFPortStatisticsReply; +import org.openflow.protocol.statistics.OFStatistics; +import org.openflow.protocol.statistics.OFStatisticsType; import org.openflow.protocol.statistics.OFTableStatistics; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * Read Service shim layer which is in charge of filtering the flow statistics * based on container. It is a Global instance. @@ -54,14 +59,15 @@ import org.openflow.protocol.statistics.OFTableStatistics; * * */ -public class ReadServiceFilter implements IPluginReadServiceFilter, - IContainerListener { +public class ReadServiceFilter implements IReadServiceFilter, IContainerListener, IOFStatisticsListener { private static final Logger logger = LoggerFactory .getLogger(ReadServiceFilter.class); private IController controller = null; private IOFStatisticsManager statsMgr = null; private Map> containerToNc; + private Map> containerToNode; private Map> containerToNt; + private ConcurrentMap readFilterInternalListeners; public void setController(IController core) { this.controller = core; @@ -73,6 +79,39 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, } } + public void setReadFilterInternalListener(Map props, IReadFilterInternalListener s) { + if (props == null) { + logger.error("Failed setting Read Filter Listener, property map is null."); + return; + } + String containerName = (String) props.get("containerName"); + if (containerName == null) { + logger.error("Failed setting Read Filter Listener, container name not supplied."); + return; + } + if ((this.readFilterInternalListeners != null) && !this.readFilterInternalListeners.containsValue(s)) { + this.readFilterInternalListeners.put(containerName, s); + logger.trace("Added Read Filter Listener for container {}", containerName); + } + } + + public void unsetReadFilterInternalListener(Map props, IReadFilterInternalListener s) { + if (props == null) { + logger.error("Failed unsetting Read Filter Listener, property map is null."); + return; + } + String containerName = (String) props.get("containerName"); + if (containerName == null) { + logger.error("Failed unsetting Read Filter Listener, containerName not supplied"); + return; + } + if ((this.readFilterInternalListeners != null) && this.readFilterInternalListeners.get(containerName) != null + && this.readFilterInternalListeners.get(containerName).equals(s)) { + this.readFilterInternalListeners.remove(containerName); + logger.trace("Removed Read Filter Listener for container {}", containerName); + } + } + /** * Function called by the dependency manager when all the required * dependencies are satisfied @@ -81,6 +120,8 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, void init() { containerToNc = new HashMap>(); containerToNt = new HashMap>(); + containerToNode = new HashMap>(); + readFilterInternalListeners = new ConcurrentHashMap(); } /** @@ -131,9 +172,20 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, long sid = (Long) node.getID(); OFMatch ofMatch = new FlowConverter(flow).getOFMatch(); - List ofList = (cached == true) ? statsMgr - .getOFFlowStatistics(sid, ofMatch) : statsMgr.queryStatistics( - sid, OFStatisticsType.FLOW, ofMatch); + List ofList; + if (cached == true){ + ofList = statsMgr.getOFFlowStatistics(sid, ofMatch, flow.getPriority()); + } else { + ofList = statsMgr.queryStatistics(sid, OFStatisticsType.FLOW, ofMatch); + for (OFStatistics ofStat : ofList) { + if (((OFFlowStatisticsReply)ofStat).getPriority() == flow.getPriority()){ + ofList = new ArrayList(1); + ofList.add(ofStat); + break; + } + } + } + /* * Convert and filter the statistics per container @@ -212,7 +264,7 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, } /** - * Filters a list of FlowOnNode elements based on the container + * Filters a list of OFStatistics elements based on the container * * @param container * @param nodeId @@ -333,8 +385,7 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, * @param flow * @return */ - private boolean flowVlanBelongsToContainer(String container, Node node, - Flow flow) { + private boolean flowVlanBelongsToContainer(String container, Node node, Flow flow) { return true; // Always true for now } @@ -363,7 +414,7 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, // If an outgoing port is specified, it must belong to this container for (Action action : flow.getActions()) { if (action.getType() == ActionType.OUTPUT) { - NodeConnector outPort = (NodeConnector) ((Output) action) + NodeConnector outPort = ((Output) action) .getPort(); if (!containerOwnsNodeConnector(container, outPort)) { return false; @@ -374,49 +425,69 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, } @Override - public void containerFlowUpdated(String containerName, - ContainerFlow previousFlow, ContainerFlow currentFlow, UpdateType t) { - + public void containerFlowUpdated(String containerName, ContainerFlow previousFlow, + ContainerFlow currentFlow, UpdateType t) { + // TODO } @Override public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType type) { - Set target = null; switch (type) { case ADDED: if (!containerToNc.containsKey(containerName)) { - containerToNc.put(containerName, new HashSet()); + containerToNc.put(containerName, + Collections.newSetFromMap(new ConcurrentHashMap())); } containerToNc.get(containerName).add(p); - break; - case CHANGED: + if (!containerToNode.containsKey(containerName)) { + containerToNode.put(containerName, new HashSet()); + } + containerToNode.get(containerName).add(p.getNode()); break; case REMOVED: - target = containerToNc.get(containerName); - if (target != null) { - target.remove(p); + Set ncSet = containerToNc.get(containerName); + if (ncSet != null) { + //remove this nc from container map + ncSet.remove(p); + + //check if there are still ports of this node in this container + //and if not, remove its mapping + boolean nodeInContainer = false; + Node node = p.getNode(); + for (NodeConnector nodeConnector : ncSet) { + if (nodeConnector.getNode().equals(node)){ + nodeInContainer = true; + break; + } + } + if (! nodeInContainer) { + Set nodeSet = containerToNode.get(containerName); + if (nodeSet != null) { + nodeSet.remove(node); + } + } } break; + case CHANGED: default: } } @Override - public void tagUpdated(String containerName, Node n, short oldTag, - short newTag, UpdateType t) { + public void tagUpdated(String containerName, Node n, short oldTag, short newTag, UpdateType t) { // Not interested in this event } @Override public void containerModeUpdated(UpdateType t) { - // do nothing + // Not interested in this event } @Override - public NodeConnectorStatistics readNodeConnector(String containerName, - NodeConnector connector, boolean cached) { + public NodeConnectorStatistics readNodeConnector( + String containerName, NodeConnector connector, boolean cached) { if (!containerOwnsNodeConnector(containerName, connector)) { return null; } @@ -470,30 +541,88 @@ public class ReadServiceFilter implements IPluginReadServiceFilter, Node node = table.getNode(); long sid = (Long) node.getID(); Byte tableId = (Byte) table.getID(); - List ofList = (cached == true) ? statsMgr - .getOFTableStatistics(sid, tableId) : statsMgr.queryStatistics( - sid, OFStatisticsType.TABLE, tableId); + List ofList = (cached == true) ? statsMgr.getOFTableStatistics(sid, tableId) : + statsMgr.queryStatistics(sid, OFStatisticsType.TABLE, tableId); - List ntStatistics = new TableStatisticsConverter( - sid, ofList).getNodeTableStatsList(); + List ntStatistics = + new TableStatisticsConverter(sid, ofList).getNodeTableStatsList(); - return (ntStatistics.isEmpty()) ? new NodeTableStatistics() - : ntStatistics.get(0); + return (ntStatistics.isEmpty()) ? new NodeTableStatistics() : ntStatistics.get(0); } @Override - public List readAllNodeTable(String containerName, - Node node, boolean cached) { + public List readAllNodeTable(String containerName, Node node, boolean cached) { long sid = (Long) node.getID(); - List ofList = (cached == true) ? statsMgr - .getOFTableStatistics(sid) : statsMgr.queryStatistics(sid, - OFStatisticsType.FLOW, null); + List ofList = (cached == true) ? + statsMgr.getOFTableStatistics(sid) : statsMgr.queryStatistics(sid, OFStatisticsType.FLOW, null); - List filteredList = filterTableListPerContainer( - containerName, sid, ofList); + List filteredList = filterTableListPerContainer(containerName, sid, ofList); + + return new TableStatisticsConverter(sid, filteredList).getNodeTableStatsList(); + } + + @Override + public void descriptionStatisticsRefreshed(Long switchId, List description) { + String container; + Node node = NodeCreator.createOFNode(switchId); + NodeDescription nodeDescription = new DescStatisticsConverter(description).getHwDescription(); + for (Map.Entry l : readFilterInternalListeners.entrySet()) { + container = l.getKey(); + if (container == GlobalConstants.DEFAULT.toString() + || (containerToNode.containsKey(container) && containerToNode.get(container).contains(node))) { + l.getValue().nodeDescriptionStatisticsUpdated(node, nodeDescription); + } + } + } - return new TableStatisticsConverter(sid, filteredList) - .getNodeTableStatsList(); + @Override + public void flowStatisticsRefreshed(Long switchId, List flows) { + String container; + Node node = NodeCreator.createOFNode(switchId); + for (Map.Entry l : readFilterInternalListeners.entrySet()) { + container = l.getKey(); + + // Convert and filter the statistics per container + List flowOnNodeList = new FlowStatisticsConverter(flows).getFlowOnNodeList(node); + flowOnNodeList = filterFlowListPerContainer(container, node, flowOnNodeList); + + // notify listeners + l.getValue().nodeFlowStatisticsUpdated(node, flowOnNodeList); + } } + @Override + public void portStatisticsRefreshed(Long switchId, List ports) { + String container; + Node node = NodeCreator.createOFNode(switchId); + for (Map.Entry l : readFilterInternalListeners.entrySet()) { + container = l.getKey(); + + // Convert and filter the statistics per container + List filteredPorts = filterPortListPerContainer(container, switchId, ports); + List ncStatsList = new PortStatisticsConverter(switchId, filteredPorts) + .getNodeConnectorStatsList(); + + // notify listeners + l.getValue().nodeConnectorStatisticsUpdated(node, ncStatsList); + + } + } + + @Override + public void tableStatisticsRefreshed(Long switchId, List tables) { + String container; + Node node = NodeCreator.createOFNode(switchId); + for (Map.Entry l : readFilterInternalListeners.entrySet()) { + container = l.getKey(); + + // Convert and filter the statistics per container + List filteredList = filterTableListPerContainer(container, switchId, tables); + List tableStatsList = new TableStatisticsConverter(switchId, filteredList) + .getNodeTableStatsList(); + + // notify listeners + l.getValue().nodeTableStatisticsUpdated(node, tableStatsList); + } + } }