From: Pramila Singh Date: Tue, 16 Jul 2013 21:11:08 +0000 (-0700) Subject: Fix for maintaining properties for non-default container. X-Git-Tag: releasepom-0.1.0~281^2 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=90187806b89850300203ef904223c091262fcf3c Fix for maintaining properties for non-default container. Signed-off-by: Pramila Singh --- 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 024549de59..837426eda4 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 @@ -8,6 +8,7 @@ package org.opendaylight.controller.protocol_plugin.openflow.internal; +import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; @@ -16,6 +17,7 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.CopyOnWriteArraySet; import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimExternalListener; import org.opendaylight.controller.protocol_plugin.openflow.IInventoryShimInternalListener; @@ -27,13 +29,11 @@ import org.opendaylight.controller.protocol_plugin.openflow.core.ISwitchStateLis 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.ConstructionException; import org.opendaylight.controller.sal.core.ContainerFlow; import org.opendaylight.controller.sal.core.Description; import org.opendaylight.controller.sal.core.IContainerListener; import org.opendaylight.controller.sal.core.MacAddress; 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.Tables; @@ -64,7 +64,10 @@ public class InventoryServiceShim implements IContainerListener, private IController controller = null; private final ConcurrentMap inventoryShimInternalListeners = new ConcurrentHashMap(); private final List inventoryShimExternalListeners = new CopyOnWriteArrayList(); - private final ConcurrentMap> containerMap = new ConcurrentHashMap>(); + private final ConcurrentMap> nodeConnectorContainerMap = new ConcurrentHashMap>(); + private final ConcurrentMap> nodeContainerMap = new ConcurrentHashMap>(); + private final ConcurrentMap> nodeConnectorProps = new ConcurrentHashMap>(); + private final ConcurrentMap> nodeProps = new ConcurrentHashMap>(); void setController(IController s) { this.controller = s; @@ -162,7 +165,8 @@ public class InventoryServiceShim implements IContainerListener, this.controller.removeSwitchStateListener(this); this.inventoryShimInternalListeners.clear(); - this.containerMap.clear(); + this.nodeConnectorContainerMap.clear(); + this.nodeContainerMap.clear(); this.controller = null; } @@ -178,21 +182,24 @@ public class InventoryServiceShim implements IContainerListener, Node node = NodeCreator.createOFNode(sw.getId()); NodeConnector nodeConnector = PortConverter.toNodeConnector( m.getDesc().getPortNumber(), node); + // get node connector properties + Set props = InventoryServiceHelper.OFPortToProps(m.getDesc()); UpdateType type = null; if (m.getReason() == (byte) OFPortReason.OFPPR_ADD.ordinal()) { type = UpdateType.ADDED; + nodeConnectorProps.put(nodeConnector, props); } else if (m.getReason() == (byte) OFPortReason.OFPPR_DELETE.ordinal()) { type = UpdateType.REMOVED; + nodeConnectorProps.remove(nodeConnector); } else if (m.getReason() == (byte) OFPortReason.OFPPR_MODIFY.ordinal()) { type = UpdateType.CHANGED; + nodeConnectorProps.put(nodeConnector, props); } logger.trace("handlePortStatusMessage {} type {}", nodeConnector, type); if (type != null) { - // get node connector properties - Set props = InventoryServiceHelper.OFPortToProps(m.getDesc()); notifyInventoryShimListener(nodeConnector, type, props); } } @@ -207,6 +214,12 @@ public class InventoryServiceShim implements IContainerListener, Map> ncProps = InventoryServiceHelper .OFSwitchToProps(sw); for (Map.Entry> entry : ncProps.entrySet()) { + Set props = new HashSet(); + Set prop = entry.getValue(); + if (prop != null) { + props.addAll(prop); + } + nodeConnectorProps.put(entry.getKey(), props); notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED, entry.getValue()); } @@ -242,48 +255,68 @@ public class InventoryServiceShim implements IContainerListener, } @Override - public void nodeConnectorUpdated(String containerName, NodeConnector p, - UpdateType t) { - logger.debug("nodeConnectorUpdated: {} type {} for container {}", - new Object[] { p, t, containerName }); - if (this.containerMap == null) { - logger.error("containerMap is NULL"); - return; + public void nodeConnectorUpdated(String containerName, NodeConnector p, UpdateType t) { + logger.debug("nodeConnectorUpdated: {} type {} for container {}", new Object[] { p, t, containerName }); + Node node = p.getNode(); + Set ncContainers = this.nodeConnectorContainerMap.get(p); + Set nodeContainers = this.nodeContainerMap.get(node); + if (ncContainers == null) { + ncContainers = new CopyOnWriteArraySet(); } - List containers = this.containerMap.get(p); - if (containers == null) { - containers = new CopyOnWriteArrayList(); + if (nodeContainers == null) { + nodeContainers = new CopyOnWriteArraySet(); } - boolean updateMap = false; + boolean notifyNodeUpdate = false; + switch (t) { case ADDED: - if (!containers.contains(containerName)) { - containers.add(containerName); - updateMap = true; + if (ncContainers.add(containerName)) { + this.nodeConnectorContainerMap.put(p, ncContainers); + } + if (nodeContainers.add(containerName)) { + this.nodeContainerMap.put(node, nodeContainers); + notifyNodeUpdate = true; } break; case REMOVED: - if (containers.contains(containerName)) { - containers.remove(containerName); - updateMap = true; + if (ncContainers.remove(containerName)) { + if (ncContainers.isEmpty()) { + // Do cleanup to reduce memory footprint if no + // elements to be tracked + this.nodeConnectorContainerMap.remove(p); + } else { + this.nodeConnectorContainerMap.put(p, ncContainers); + } + } + boolean nodeContainerUpdate = true; + for (NodeConnector nc : nodeConnectorContainerMap.keySet()) { + if ((nc.getNode().equals(node)) && (nodeConnectorContainerMap.get(nc).contains(containerName))) { + nodeContainerUpdate = false; + break; + } + } + if (nodeContainerUpdate) { + nodeContainers.remove(containerName); + notifyNodeUpdate = true; + if (nodeContainers.isEmpty()) { + this.nodeContainerMap.remove(node); + } else { + this.nodeContainerMap.put(node, nodeContainers); + } } break; case CHANGED: break; } - if (updateMap) { - if (containers.isEmpty()) { - // Do cleanup to reduce memory footprint if no - // elements to be tracked - this.containerMap.remove(p); - } else { - this.containerMap.put(p, containers); - } - } + Set ncProp = nodeConnectorProps.get(p); // notify InventoryService - notifyInventoryShimInternalListener(containerName, p, t, null); - notifyInventoryShimInternalListener(containerName, p.getNode(), t, null); + notifyInventoryShimInternalListener(containerName, p, t, ncProp); + + if (notifyNodeUpdate) { + Set nodeProp = nodeProps.get(node); + notifyInventoryShimInternalListener(containerName, node, t, nodeProp); + } } private void notifyInventoryShimExternalListener(Node node, @@ -316,21 +349,13 @@ public class InventoryServiceShim implements IContainerListener, /* * Notify all internal and external listeners */ - private void notifyInventoryShimListener(NodeConnector nodeConnector, - UpdateType type, Set props) { - // Always notify default InventoryService. Store properties in default - // one. - notifyInventoryShimInternalListener(GlobalConstants.DEFAULT.toString(), - nodeConnector, type, props); - - // Now notify other containers - List containers = containerMap.get(nodeConnector); - if (containers != null) { - for (String container : containers) { - // no property stored in container components. - notifyInventoryShimInternalListener(container, nodeConnector, - type, null); - } + private void notifyInventoryShimListener(NodeConnector nodeConnector, UpdateType type, Set props) { + // notify other containers + Set containers = (nodeConnectorContainerMap.get(nodeConnector) == null) ? new HashSet() + : new HashSet(nodeConnectorContainerMap.get(nodeConnector)); + containers.add(GlobalConstants.DEFAULT.toString()); + for (String container : containers) { + notifyInventoryShimInternalListener(container, nodeConnector, type, props); } // Notify DiscoveryService @@ -340,34 +365,13 @@ public class InventoryServiceShim implements IContainerListener, /* * Notify all internal and external listeners */ - private void notifyInventoryShimListener(Node node, UpdateType type, - Set props) { - switch (type) { - case ADDED: - // Notify only the default Inventory Service - IInventoryShimInternalListener inventoryShimDefaultListener = inventoryShimInternalListeners - .get(GlobalConstants.DEFAULT.toString()); - if (inventoryShimDefaultListener != null) { - inventoryShimDefaultListener.updateNode(node, type, props); - } - break; - case REMOVED: - // Notify all Inventory Service containers - for (IInventoryShimInternalListener inventoryShimInternalListener : inventoryShimInternalListeners - .values()) { - inventoryShimInternalListener.updateNode(node, type, null); - } - break; - case CHANGED: - // Notify only the default Inventory Service - inventoryShimDefaultListener = inventoryShimInternalListeners - .get(GlobalConstants.DEFAULT.toString()); - if (inventoryShimDefaultListener != null) { - inventoryShimDefaultListener.updateNode(node, type, props); - } - break; - default: - break; + private void notifyInventoryShimListener(Node node, UpdateType type, Set props) { + // Now notify other containers + Set containers = (nodeContainerMap.get(node) == null) ? new HashSet() : new HashSet( + nodeContainerMap.get(node)); + containers.add(GlobalConstants.DEFAULT.toString()); + for (String container : containers) { + notifyInventoryShimInternalListener(container, node, type, props); } // Notify external listener @@ -421,21 +425,19 @@ public class InventoryServiceShim implements IContainerListener, props.add(b); } + nodeProps.put(node, props); // Notify all internal and external listeners notifyInventoryShimListener(node, type, props); } private void removeNode(ISwitch sw) { - Node node; - try { - node = new Node(NodeIDType.OPENFLOW, sw.getId()); - } catch (ConstructionException e) { - logger.error("{}", e.getMessage()); + Node node = NodeCreator.createOFNode(sw.getId()); + if(node == null) { return; } - + removeNodeConnectorProps(node); + nodeProps.remove(node); UpdateType type = UpdateType.REMOVED; - // Notify all internal and external listeners notifyInventoryShimListener(node, type, null); } @@ -448,6 +450,18 @@ public class InventoryServiceShim implements IContainerListener, } } + private void removeNodeConnectorProps(Node node) { + List ncList = new ArrayList(); + for (NodeConnector nc : nodeConnectorProps.keySet()) { + if (nc.getNode().equals(node)) { + ncList.add(nc); + } + } + for (NodeConnector nc : ncList) { + nodeConnectorProps.remove(nc); + } + } + @Override public void descriptionStatisticsRefreshed(Long switchId, List descriptionStats) { Node node = NodeCreator.createOFNode(switchId); diff --git a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java index 7fd9bc17d1..9ff3f91850 100644 --- a/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java +++ b/opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManagerImpl.java @@ -58,7 +58,6 @@ import org.opendaylight.controller.sal.utils.HexEncode; import org.opendaylight.controller.sal.utils.IObjectReader; import org.opendaylight.controller.sal.utils.ObjectReader; import org.opendaylight.controller.sal.utils.ObjectWriter; -import org.opendaylight.controller.sal.utils.ServiceHelper; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.sal.utils.StatusCode; import org.opendaylight.controller.switchmanager.IInventoryListener; @@ -888,10 +887,8 @@ CommandProvider { } // copy node properties from plugin - if (props != null) { - for (Property prop : props) { - propMap.put(prop.getName(), prop); - } + for (Property prop : props) { + propMap.put(prop.getName(), prop); } if (propMapCurr == null) { @@ -934,7 +931,6 @@ CommandProvider { @Override public void updateNodeConnector(NodeConnector nodeConnector, UpdateType type, Set props) { - Node node = nodeConnector.getNode(); Map propMap = new HashMap(); log.debug("updateNodeConnector: {} type {} props {} for container {}", @@ -954,14 +950,12 @@ CommandProvider { } } else { addNodeConnectorProp(nodeConnector, null); - addNodeProps(node, null); } addSpanPort(nodeConnector); break; case REMOVED: removeNodeConnectorAllProps(nodeConnector); - removeNodeProps(node); // clean up span config removeSpanPort(nodeConnector); @@ -990,23 +984,15 @@ CommandProvider { */ @Override public Map getNodeProps(Node node) { - if (isDefaultContainer) { - Map rv = null; - if (this.nodeProps != null) { - rv = this.nodeProps.get(node); - if (rv != null) { - /* make a copy of it */ - rv = new HashMap(rv); - } + Map rv = new HashMap(); + if (this.nodeProps != null) { + rv = this.nodeProps.get(node); + if (rv != null) { + /* make a copy of it */ + rv = new HashMap(rv); } - return rv; - } else { - // get it from default container - ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper - .getInstance(ISwitchManager.class, - GlobalConstants.DEFAULT.toString(), this); - return defaultSwitchManager.getNodeProps(node); } + return rv; } @Override @@ -1036,7 +1022,7 @@ CommandProvider { return; } if (!propMapCurr.get(prop.getName()).equals(nodeProps.get(node).get(prop.getName()))) { - log.warn("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID()); + log.debug("Cluster conflict: Unable to add property {} to node {}.", prop.getName(), node.getID()); return; } } @@ -1135,24 +1121,15 @@ CommandProvider { } @Override - public Map getNodeConnectorProps( - NodeConnector nodeConnector) { - if (isDefaultContainer) { - Map rv = null; - if (this.nodeConnectorProps != null) { - rv = this.nodeConnectorProps.get(nodeConnector); - if (rv != null) { - rv = new HashMap(rv); - } + public Map getNodeConnectorProps(NodeConnector nodeConnector) { + Map rv = new HashMap(); + if (this.nodeConnectorProps != null) { + rv = this.nodeConnectorProps.get(nodeConnector); + if (rv != null) { + rv = new HashMap(rv); } - return rv; - } else { - // get it from default container - ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper - .getInstance(ISwitchManager.class, - GlobalConstants.DEFAULT.toString(), this); - return defaultSwitchManager.getNodeConnectorProps(nodeConnector); } + return rv; } @Override