From 024912bcf6b5c303ee6d4e87b163ff36bb5d806e Mon Sep 17 00:00:00 2001 From: Pramila Singh Date: Thu, 12 Sep 2013 11:21:45 -0700 Subject: [PATCH] Fix for cache cleanup in protocol plugin on container deletion Change-Id: I5c16211ea12c384726a5a9d3f1cc23d40c1d0d3f Signed-off-by: Pramila Singh --- .../openflow/internal/Activator.java | 34 +++++------ .../openflow/internal/DataPacketMuxDemux.java | 57 +++++++++++++------ .../openflow/internal/DiscoveryService.java | 14 ++--- .../internal/FlowProgrammerService.java | 17 ++++-- .../internal/InventoryServiceShim.java | 45 ++++++++++++++- .../openflow/internal/ReadServiceFilter.java | 16 +++++- .../internal/TopologyServiceShim.java | 37 ++++++++++-- 7 files changed, 163 insertions(+), 57 deletions(-) diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java index 05736f779e..ee62204f3f 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/Activator.java @@ -31,6 +31,7 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.internal.Contro import org.opendaylight.controller.sal.connection.IPluginInConnectionService; import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.flowprogrammer.IPluginInFlowProgrammerService; @@ -273,12 +274,9 @@ public class Activator extends ComponentActivatorAbstractBase { // by SAL props.put(GlobalConstants.PROTOCOLPLUGINTYPE.toString(), Node.NodeIDType.OPENFLOW); c.setInterface( - new String[] { - IPluginInFlowProgrammerService.class.getName(), - IMessageListener.class.getName(), - IContainerListener.class.getName(), - IInventoryShimExternalListener.class.getName() }, - props); + new String[] { IPluginInFlowProgrammerService.class.getName(), IMessageListener.class.getName(), + IContainerListener.class.getName(), IInventoryShimExternalListener.class.getName(), + IContainerAware.class.getName() }, props); c.add(createServiceDependency() .setService(IController.class, "(name=Controller)") @@ -300,10 +298,8 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(ReadServiceFilter.class)) { - c.setInterface(new String[] { - IReadServiceFilter.class.getName(), - IContainerListener.class.getName(), - IOFStatisticsListener.class.getName() }, null); + c.setInterface(new String[] { IReadServiceFilter.class.getName(), IContainerListener.class.getName(), + IOFStatisticsListener.class.getName(), IContainerAware.class.getName() }, null); c.add(createServiceDependency() .setService(IController.class, "(name=Controller)") @@ -338,9 +334,7 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(DiscoveryService.class)) { // export the service c.setInterface( - new String[] { - IInventoryShimExternalListener.class.getName(), - IDataPacketListen.class.getName(), + new String[] { IInventoryShimExternalListener.class.getName(), IDataPacketListen.class.getName(), IContainerListener.class.getName() }, null); c.add(createServiceDependency() @@ -369,9 +363,8 @@ public class Activator extends ComponentActivatorAbstractBase { // DataPacket mux/demux services, which is teh actual engine // doing the packet switching if (imp.equals(DataPacketMuxDemux.class)) { - c.setInterface(new String[] { IDataPacketMux.class.getName(), - IContainerListener.class.getName(), - IInventoryShimExternalListener.class.getName() }, null); + c.setInterface(new String[] { IDataPacketMux.class.getName(), IContainerListener.class.getName(), + IInventoryShimExternalListener.class.getName(), IContainerAware.class.getName() }, null); c.add(createServiceDependency() .setService(IController.class, "(name=Controller)") @@ -419,7 +412,7 @@ public class Activator extends ComponentActivatorAbstractBase { if (imp.equals(InventoryServiceShim.class)) { c.setInterface(new String[] { IContainerListener.class.getName(), - IOFStatisticsListener.class.getName()}, null); + IOFStatisticsListener.class.getName(), IContainerAware.class.getName() }, null); c.add(createServiceDependency() .setService(IController.class, "(name=Controller)") @@ -448,10 +441,9 @@ public class Activator extends ComponentActivatorAbstractBase { } if (imp.equals(TopologyServiceShim.class)) { - c.setInterface(new String[] { IDiscoveryListener.class.getName(), - IContainerListener.class.getName(), - IRefreshInternalProvider.class.getName(), - IInventoryShimExternalListener.class.getName() }, null); + c.setInterface(new String[] { IDiscoveryListener.class.getName(), IContainerListener.class.getName(), + IRefreshInternalProvider.class.getName(), IInventoryShimExternalListener.class.getName(), + IContainerAware.class.getName() }, null); c.add(createServiceDependency() .setService(ITopologyServiceShimListener.class) .setCallbacks("setTopologyServiceShimListener", diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DataPacketMuxDemux.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DataPacketMuxDemux.java index 7a01d3bd19..a1fcd1ab23 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DataPacketMuxDemux.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DataPacketMuxDemux.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -22,19 +23,10 @@ import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExtern import org.opendaylight.controller.protocol_plugin.openflow.core.IController; import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageListener; import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; -import org.openflow.protocol.OFMessage; -import org.openflow.protocol.OFPacketIn; -import org.openflow.protocol.OFPacketOut; -import org.openflow.protocol.OFPort; -import org.openflow.protocol.OFType; -import org.openflow.protocol.action.OFAction; -import org.openflow.protocol.action.OFActionOutput; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.ConstructionException; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -45,9 +37,18 @@ import org.opendaylight.controller.sal.packet.PacketResult; import org.opendaylight.controller.sal.packet.RawPacket; import org.opendaylight.controller.sal.utils.GlobalConstants; import org.opendaylight.controller.sal.utils.HexEncode; +import org.openflow.protocol.OFMessage; +import org.openflow.protocol.OFPacketIn; +import org.openflow.protocol.OFPacketOut; +import org.openflow.protocol.OFPort; +import org.openflow.protocol.OFType; +import org.openflow.protocol.action.OFAction; +import org.openflow.protocol.action.OFActionOutput; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class DataPacketMuxDemux implements IContainerListener, - IMessageListener, IDataPacketMux, IInventoryShimExternalListener { + IMessageListener, IDataPacketMux, IInventoryShimExternalListener, IContainerAware { protected static final Logger logger = LoggerFactory .getLogger(DataPacketMuxDemux.class); private IController controller = null; @@ -375,14 +376,13 @@ public class DataPacketMuxDemux implements IContainerListener, } switch (t) { case ADDED: - if (!fSpecs.contains(previousFlow)) { - fSpecs.add(previousFlow); + if (!fSpecs.contains(currentFlow)) { + fSpecs.add(currentFlow); } + container2FlowSpecs.put(containerName, fSpecs); break; case REMOVED: - if (fSpecs.contains(previousFlow)) { - fSpecs.remove(previousFlow); - } + fSpecs.remove(currentFlow); break; case CHANGED: break; @@ -452,4 +452,29 @@ public class DataPacketMuxDemux implements IContainerListener, UpdateType type, Set props) { // do nothing } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + Set removeNodeConnectorSet = new HashSet(); + for (Map.Entry> entry : nc2Container.entrySet()) { + List ncContainers = entry.getValue(); + if (ncContainers.contains(containerName)) { + NodeConnector nodeConnector = entry.getKey(); + removeNodeConnectorSet.add(nodeConnector); + } + } + for (NodeConnector nodeConnector : removeNodeConnectorSet) { + List ncContainers = nc2Container.get(nodeConnector); + ncContainers.remove(containerName); + if (ncContainers.isEmpty()) { + nc2Container.remove(nodeConnector); + } + } + container2FlowSpecs.remove(containerName); + } } diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java index 0895d9af27..592e336b0b 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/DiscoveryService.java @@ -33,17 +33,11 @@ import org.opendaylight.controller.protocol_plugin.openflow.IInventoryProvider; import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener; import org.opendaylight.controller.protocol_plugin.openflow.core.IController; import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; -import org.openflow.protocol.OFPhysicalPort; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.Config; import org.opendaylight.controller.sal.core.ConstructionException; -import org.opendaylight.controller.sal.core.Edge; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.Edge; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -61,6 +55,11 @@ import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.NetUtils; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.NodeCreator; +import org.openflow.protocol.OFPhysicalPort; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The class describes neighbor discovery service for an OpenFlow network. @@ -1693,4 +1692,5 @@ public class DiscoveryService implements IInventoryShimExternalListener, IDataPa } return ports; } + } diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java index c55a88cd3f..88b75b196d 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/FlowProgrammerService.java @@ -25,6 +25,7 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.IMessageListene import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitch; import org.opendaylight.controller.sal.connection.IPluginOutConnectionService; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.Node.NodeIDType; @@ -58,7 +59,7 @@ import org.slf4j.LoggerFactory; */ public class FlowProgrammerService implements IPluginInFlowProgrammerService, IMessageListener, IContainerListener, IInventoryShimExternalListener, - CommandProvider { + CommandProvider, IContainerAware { private static final Logger log = LoggerFactory .getLogger(FlowProgrammerService.class); private IController controller; @@ -465,8 +466,6 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, @Override public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType type) { - Set target = null; - switch (type) { case ADDED: if (!containerToNc.containsKey(containerName)) { @@ -477,7 +476,7 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, case CHANGED: break; case REMOVED: - target = containerToNc.get(containerName); + Set target = containerToNc.get(containerName); if (target != null) { target.remove(p); } @@ -800,4 +799,14 @@ public class FlowProgrammerService implements IPluginInFlowProgrammerService, ci.println("Max num of async messages sent prior to the Barrier message is " + barrierMessagePriorCount); } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + containerToNc.remove(containerName); + } } diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java index 9e01796806..adc121816b 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java @@ -32,6 +32,7 @@ import org.opendaylight.controller.sal.core.Buffers; import org.opendaylight.controller.sal.core.Capabilities; import org.opendaylight.controller.sal.core.ContainerFlow; import org.opendaylight.controller.sal.core.Description; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.MacAddress; import org.opendaylight.controller.sal.core.Node; @@ -59,7 +60,7 @@ import org.slf4j.LoggerFactory; * */ public class InventoryServiceShim implements IContainerListener, - IMessageListener, ISwitchStateListener, IOFStatisticsListener { + IMessageListener, ISwitchStateListener, IOFStatisticsListener, IContainerAware { protected static final Logger logger = LoggerFactory .getLogger(InventoryServiceShim.class); private IController controller = null; @@ -139,7 +140,7 @@ public class InventoryServiceShim implements IContainerListener, } void setInventoryShimExternalListener(IInventoryShimExternalListener s) { - logger.trace("Set inventoryShimExternalListener"); + logger.trace("Set inventoryShimExternalListener {}", s); if ((this.inventoryShimExternalListeners != null) && !this.inventoryShimExternalListeners.contains(s)) { this.inventoryShimExternalListeners.add(s); @@ -147,6 +148,7 @@ public class InventoryServiceShim implements IContainerListener, } void unsetInventoryShimExternalListener(IInventoryShimExternalListener s) { + logger.trace("Unset inventoryShimExternalListener {}", s); if ((this.inventoryShimExternalListeners != null) && this.inventoryShimExternalListeners.contains(s)) { this.inventoryShimExternalListeners.remove(s); @@ -584,4 +586,43 @@ public class InventoryServiceShim implements IContainerListener, public void tableStatisticsRefreshed(Long switchId, List tables) { // Nothing to do } + + @Override + public void containerCreate(String containerName) { + // Nothing to do + } + + @Override + public void containerDestroy(String containerName) { + Set removeNodeConnectorSet = new HashSet(); + Set removeNodeSet = new HashSet(); + for (Map.Entry> entry : nodeConnectorContainerMap.entrySet()) { + Set ncContainers = entry.getValue(); + if (ncContainers.contains(containerName)) { + NodeConnector nodeConnector = entry.getKey(); + removeNodeConnectorSet.add(nodeConnector); + } + } + for (Map.Entry> entry : nodeContainerMap.entrySet()) { + Set nodeContainers = entry.getValue(); + if (nodeContainers.contains(containerName)) { + Node node = entry.getKey(); + removeNodeSet.add(node); + } + } + for (NodeConnector nodeConnector : removeNodeConnectorSet) { + Set ncContainers = nodeConnectorContainerMap.get(nodeConnector); + ncContainers.remove(containerName); + if (ncContainers.isEmpty()) { + nodeConnectorContainerMap.remove(nodeConnector); + } + } + for (Node node : removeNodeSet) { + Set nodeContainers = nodeContainerMap.get(node); + nodeContainers.remove(containerName); + if (nodeContainers.isEmpty()) { + nodeContainerMap.remove(node); + } + } + } } 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 b877eb0ee7..d7bf2e2258 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 @@ -27,6 +27,7 @@ import org.opendaylight.controller.sal.action.Action; import org.opendaylight.controller.sal.action.ActionType; import org.opendaylight.controller.sal.action.Output; import org.opendaylight.controller.sal.core.ContainerFlow; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -55,7 +56,7 @@ 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. */ -public class ReadServiceFilter implements IReadServiceFilter, IContainerListener, IOFStatisticsListener { +public class ReadServiceFilter implements IReadServiceFilter, IContainerListener, IOFStatisticsListener, IContainerAware { private static final Logger logger = LoggerFactory .getLogger(ReadServiceFilter.class); private IController controller = null; @@ -632,4 +633,17 @@ public class ReadServiceFilter implements IReadServiceFilter, IContainerListener l.getValue().nodeTableStatisticsUpdated(node, tableStatsList); } } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + containerToNc.remove(containerName); + containerToNode.remove(containerName); + containerToNt.remove(containerName); + containerFlows.remove(containerName); + } } diff --git a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java index 400e9e8692..86583ace0a 100644 --- a/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java +++ b/opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/TopologyServiceShim.java @@ -32,15 +32,11 @@ import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExtern import org.opendaylight.controller.protocol_plugin.openflow.IOFStatisticsManager; import org.opendaylight.controller.protocol_plugin.openflow.IRefreshInternalProvider; import org.opendaylight.controller.protocol_plugin.openflow.ITopologyServiceShimListener; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - import org.opendaylight.controller.sal.core.Bandwidth; import org.opendaylight.controller.sal.core.Config; import org.opendaylight.controller.sal.core.ContainerFlow; import org.opendaylight.controller.sal.core.Edge; +import org.opendaylight.controller.sal.core.IContainerAware; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.Node; import org.opendaylight.controller.sal.core.NodeConnector; @@ -49,6 +45,10 @@ import org.opendaylight.controller.sal.core.State; import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.topology.TopoEdgeUpdate; import org.opendaylight.controller.sal.utils.GlobalConstants; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * The class describes a shim layer that relays the topology events from @@ -57,7 +57,7 @@ import org.opendaylight.controller.sal.utils.GlobalConstants; */ public class TopologyServiceShim implements IDiscoveryListener, IContainerListener, CommandProvider, IRefreshInternalProvider, - IInventoryShimExternalListener { + IInventoryShimExternalListener, IContainerAware { protected static final Logger logger = LoggerFactory .getLogger(TopologyServiceShim.class); private ConcurrentMap topologyServiceShimListeners = new ConcurrentHashMap(); @@ -916,4 +916,29 @@ public class TopologyServiceShim implements IDiscoveryListener, break; } } + + @Override + public void containerCreate(String containerName) { + // do nothing + } + + @Override + public void containerDestroy(String containerName) { + Set removeNodeConnectorSet = new HashSet(); + for (Map.Entry> entry : containerMap.entrySet()) { + List ncContainers = entry.getValue(); + if (ncContainers.contains(containerName)) { + NodeConnector nodeConnector = entry.getKey(); + removeNodeConnectorSet.add(nodeConnector); + } + } + for (NodeConnector nodeConnector : removeNodeConnectorSet) { + List ncContainers = containerMap.get(nodeConnector); + ncContainers.remove(containerName); + if (ncContainers.isEmpty()) { + containerMap.remove(nodeConnector); + } + } + edgeMap.remove(containerName); + } } -- 2.36.6