Merge "Replace exception.printStacktrace with write to log."
[controller.git] / opendaylight / switchmanager / implementation / src / main / java / org / opendaylight / controller / switchmanager / internal / SwitchManager.java
index 0705984bfe334b0eaff2ef2a0c3675c615ec3821..d82c9967425839dcc1fbd10efe74120c03efd03f 100644 (file)
@@ -16,7 +16,6 @@ import java.net.NetworkInterface;
 import java.net.SocketException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Date;
 import java.util.Dictionary;
 import java.util.EnumSet;
 import java.util.Enumeration;
@@ -34,7 +33,6 @@ import org.eclipse.osgi.framework.console.CommandInterpreter;
 import org.eclipse.osgi.framework.console.CommandProvider;
 import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
-import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterContainerServices;
 import org.opendaylight.controller.clustering.services.IClusterServices;
 import org.opendaylight.controller.configuration.IConfigurationContainerAware;
@@ -54,6 +52,7 @@ import org.opendaylight.controller.sal.core.Tier;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.inventory.IInventoryService;
 import org.opendaylight.controller.sal.inventory.IListenInventoryUpdates;
+import org.opendaylight.controller.sal.reader.NodeDescription;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.IObjectReader;
@@ -61,6 +60,7 @@ import org.opendaylight.controller.sal.utils.ObjectReader;
 import org.opendaylight.controller.sal.utils.ObjectWriter;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
 import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISpanAware;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
@@ -83,27 +83,24 @@ import org.slf4j.LoggerFactory;
  * instance per container of the network. All the node/nodeConnector properties
  * are maintained in the default container only.
  */
-public class SwitchManager implements ISwitchManager,
-IConfigurationContainerAware, IObjectReader,
-ICacheUpdateAware<Long, String>, IListenInventoryUpdates,
-CommandProvider {
+public class SwitchManager implements ISwitchManager, IConfigurationContainerAware,
+                                      IObjectReader, IListenInventoryUpdates, CommandProvider {
     private static Logger log = LoggerFactory.getLogger(SwitchManager.class);
     private static String ROOT = GlobalConstants.STARTUPHOME.toString();
-    private static final String SAVE = "Save";
     private String subnetFileName, spanFileName, switchConfigFileName;
     private final List<NodeConnector> spanNodeConnectors = new CopyOnWriteArrayList<NodeConnector>();
-    // set of Subnets keyed by the InetAddress
+    // Collection of Subnets keyed by the InetAddress
     private ConcurrentMap<InetAddress, Subnet> subnets;
     private ConcurrentMap<String, SubnetConfig> subnetsConfigList;
     private ConcurrentMap<SpanConfig, SpanConfig> spanConfigList;
     // manually configured parameters for the node such as name, tier, mode
     private ConcurrentMap<String, SwitchConfig> nodeConfigList;
-    private ConcurrentMap<Long, String> configSaveEvent;
     private ConcurrentMap<Node, Map<String, Property>> nodeProps;
     private ConcurrentMap<NodeConnector, Map<String, Property>> nodeConnectorProps;
     private ConcurrentMap<Node, Map<String, NodeConnector>> nodeConnectorNames;
     private ConcurrentMap<String, Property> controllerProps;
     private IInventoryService inventoryService;
+    private IStatisticsManager statisticsManager;
     private final Set<ISwitchManagerAware> switchManagerAware = Collections
             .synchronizedSet(new HashSet<ISwitchManagerAware>());
     private final Set<IInventoryListener> inventoryListeners = Collections
@@ -207,27 +204,27 @@ CommandProvider {
         try {
             clusterContainerService.createCache(
                     "switchmanager.subnetsConfigList",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache("switchmanager.spanConfigList",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache("switchmanager.nodeConfigList",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache("switchmanager.subnets",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache(
                     "switchmanager.configSaveEvent",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache("switchmanager.nodeProps",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache(
                     "switchmanager.nodeConnectorProps",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache(
                     "switchmanager.nodeConnectorNames",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
             clusterContainerService.createCache(
                     "switchmanager.controllerProps",
-                    EnumSet.of(IClusterServices.cacheMode.NON_TRANSACTIONAL));
+                    EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
         } catch (CacheConfigException cce) {
             log.error("\nCache configuration invalid - check cache mode");
         } catch (CacheExistException ce) {
@@ -266,12 +263,6 @@ CommandProvider {
             log.error("\nFailed to get cache for subnets");
         }
 
-        configSaveEvent = (ConcurrentMap<Long, String>) clusterContainerService
-                .getCache("switchmanager.configSaveEvent");
-        if (configSaveEvent == null) {
-            log.error("\nFailed to get cache for configSaveEvent");
-        }
-
         nodeProps = (ConcurrentMap<Node, Map<String, Property>>) clusterContainerService
                 .getCache("switchmanager.nodeProps");
         if (nodeProps == null) {
@@ -302,7 +293,6 @@ CommandProvider {
         spanConfigList = new ConcurrentHashMap<SpanConfig, SpanConfig>();
         nodeConfigList = new ConcurrentHashMap<String, SwitchConfig>();
         subnets = new ConcurrentHashMap<InetAddress, Subnet>();
-        configSaveEvent = new ConcurrentHashMap<Long, String>();
         nodeProps = new ConcurrentHashMap<Node, Map<String, Property>>();
         nodeConnectorProps = new ConcurrentHashMap<NodeConnector, Map<String, Property>>();
         nodeConnectorNames = new ConcurrentHashMap<Node, Map<String, NodeConnector>>();
@@ -401,19 +391,21 @@ CommandProvider {
                 Set<NodeConnector> sp = conf.getSubnetNodeConnectors();
                 subnet.addNodeConnectors(sp);
             }
-            boolean result = false;
+            boolean putNewSubnet = false;
             if(subnetCurr == null) {
                 if(subnets.putIfAbsent(conf.getIPnum(), subnet) == null) {
-                    result = true;
+                    putNewSubnet = true;
                 }
             } else {
-                result = subnets.replace(conf.getIPnum(), subnetCurr, subnet);
+                putNewSubnet = subnets.replace(conf.getIPnum(), subnetCurr, subnet);
             }
-            if(!result) {
+            if(!putNewSubnet) {
                 String msg = "Cluster conflict: Conflict while adding the subnet " + conf.getIPnum();
                 return new Status(StatusCode.CONFLICT, msg);
             }
-        } else { // This is the deletion of the whole subnet
+
+        // Subnet removal case
+        } else {
             subnets.remove(conf.getIPnum());
         }
         return new Status(StatusCode.SUCCESS);
@@ -435,7 +427,7 @@ CommandProvider {
         return new Status(StatusCode.SUCCESS);
     }
 
-    private Status addRemoveSubnet(SubnetConfig conf, boolean add) {
+    private Status addRemoveSubnet(SubnetConfig conf, boolean isAdding) {
         // Valid config check
         if (!conf.isValidConfig()) {
             String msg = "Invalid Subnet configuration";
@@ -443,13 +435,13 @@ CommandProvider {
             return new Status(StatusCode.BADREQUEST, msg);
         }
 
-        if (add) {
+        if (isAdding) {
             // Presence check
             if (subnetsConfigList.containsKey(conf.getName())) {
                 return new Status(StatusCode.CONFLICT,
-                        "Same subnet config already exists");
+                        "Subnet with the specified name already configured.");
             }
-            // Semantyc check
+            // Semantic check
             Status rc = semanticCheck(conf);
             if (!rc.isSuccess()) {
                 return rc;
@@ -457,13 +449,13 @@ CommandProvider {
         }
 
         // Update Database
-        Status rc = updateDatabase(conf, add);
+        Status rc = updateDatabase(conf, isAdding);
 
         if (rc.isSuccess()) {
             // Update Configuration
-            rc = updateConfig(conf, add);
+            rc = updateConfig(conf, isAdding);
             if(!rc.isSuccess()) {
-                updateDatabase(conf, (!add));
+                updateDatabase(conf, (!isAdding));
             }
         }
 
@@ -512,8 +504,8 @@ CommandProvider {
         Subnet sub = subCurr.clone();
         Set<NodeConnector> sp = confCurr.getNodeConnectors(switchPorts);
         sub.addNodeConnectors(sp);
-        boolean subnetsReplace = subnets.replace(confCurr.getIPnum(), subCurr, sub);
-        if (!subnetsReplace) {
+        boolean subnetsReplaced = subnets.replace(confCurr.getIPnum(), subCurr, sub);
+        if (!subnetsReplaced) {
             String msg = "Cluster conflict: Conflict while adding ports to the subnet " + name;
             return new Status(StatusCode.CONFLICT, msg);
         }
@@ -521,8 +513,8 @@ CommandProvider {
         // Update Configuration
         SubnetConfig conf = confCurr.clone();
         conf.addNodeConnectors(switchPorts);
-        boolean result = subnetsConfigList.replace(name, confCurr, conf);
-        if (!result) {
+        boolean configReplaced = subnetsConfigList.replace(name, confCurr, conf);
+        if (!configReplaced) {
             // TODO: recovery using Transactionality
             String msg = "Cluster conflict: Conflict while adding ports to the subnet " + name;
             return new Status(StatusCode.CONFLICT, msg);
@@ -636,7 +628,7 @@ CommandProvider {
         }
 
         for (SwitchConfig conf : confList.values()) {
-            updateSwitchConfig(conf);
+            updateNodeConfig(conf);
         }
     }
 
@@ -696,18 +688,43 @@ CommandProvider {
         }
 
         Map<String, Property> updateProperties = switchConfig.getNodeProperties();
-        String nodeId = switchConfig.getNodeId();
         ForwardingMode mode = (ForwardingMode) updateProperties.get(ForwardingMode.name);
         if (mode != null) {
             if (isDefaultContainer) {
                 if (!mode.isValid()) {
-                    return new Status(StatusCode.BADREQUEST, "Invalid Forwarding Mode Value.");
+                    return new Status(StatusCode.BADREQUEST, "Invalid Forwarding Mode Value");
                 }
             } else {
                 return new Status(StatusCode.NOTACCEPTABLE,
                         "Forwarding Mode modification is allowed only in default container");
             }
         }
+
+        Description description = (Description) switchConfig.getProperty(Description.propertyName);
+        String nodeId = switchConfig.getNodeId();
+        Node node = Node.fromString(nodeId);
+        NodeDescription nodeDesc = (this.statisticsManager == null) ? null : this.statisticsManager
+                .getNodeDescription(node);
+        String advertisedDesc = (nodeDesc == null) ? "" : nodeDesc.getDescription();
+        if (description != null && description.getValue() != null) {
+            if (description.getValue().isEmpty() || description.getValue().equals(advertisedDesc)) {
+                updateProperties.remove(Description.propertyName);
+                switchConfig = new SwitchConfig(nodeId, updateProperties);
+            } else {
+                // check if description is configured or was published by any other node
+                for (Map.Entry<Node, Map<String, Property>> entry : nodeProps.entrySet()) {
+                    Node n = entry.getKey();
+                    Description desc = (Description) getNodeProp(n, Description.propertyName);
+                    NodeDescription nDesc = (this.statisticsManager == null) ? null : this.statisticsManager
+                            .getNodeDescription(n);
+                    String advDesc = (nDesc == null) ? "" : nDesc.getDescription();
+                    if ((description.equals(desc) || description.getValue().equals(advDesc)) && !node.equals(n)) {
+                        return new Status(StatusCode.CONFLICT, "Node name already in use");
+                    }
+                }
+            }
+        }
+
         boolean modeChange = false;
         SwitchConfig sc = nodeConfigList.get(nodeId);
         Map<String, Property> prevNodeProperties = new HashMap<String, Property>();
@@ -741,30 +758,32 @@ CommandProvider {
                 }
             }
         }
-        Node node = Node.fromString(nodeId);
         Map<String, Property> propMapCurr = nodeProps.get(node);
         if (propMapCurr == null) {
             return new Status(StatusCode.SUCCESS);
         }
         Map<String, Property> propMap = new HashMap<String, Property>(propMapCurr);
-        if (!prevNodeProperties.isEmpty()) {
-            for (String prop : prevNodeProperties.keySet()) {
-                if (!updateProperties.containsKey(prop)) {
-                    if (prop.equals(Description.propertyName)) {
-                        Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
-                        if (nodeProp.get(node) != null) {
-                            propMap.put(Description.propertyName, nodeProp.get(node).get(Description.propertyName));
-                            continue;
-                        }
+        for (Map.Entry<String, Property> entry : prevNodeProperties.entrySet()) {
+            String prop = entry.getKey();
+            if (!updateProperties.containsKey(prop)) {
+                if (prop.equals(Description.propertyName)) {
+                    if (!advertisedDesc.isEmpty()) {
+                        Property desc = new Description(advertisedDesc);
+                        propMap.put(Description.propertyName, desc);
                     }
-                    propMap.remove(prop);
+                    continue;
+                } else if (prop.equals(ForwardingMode.name)) {
+                    Property defaultMode = new ForwardingMode(ForwardingMode.REACTIVE_FORWARDING);
+                    propMap.put(ForwardingMode.name, defaultMode);
+                    continue;
                 }
+                propMap.remove(prop);
             }
         }
         propMap.putAll(updateProperties);
         if (!nodeProps.replace(node, propMapCurr, propMap)) {
             // TODO rollback using Transactionality
-            return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration.");
+            return new Status(StatusCode.CONFLICT, "Cluster conflict: Unable to update node configuration");
         }
         if (modeChange) {
             notifyModeChange(node, (mode == null) ? false : mode.isProactive());
@@ -782,7 +801,8 @@ CommandProvider {
         Map<String, Property> propMapCurr = nodeProps.get(node);
         if ((propMapCurr != null) && (nodeProperties != null) && (!nodeProperties.isEmpty())) {
             Map<String, Property> propMap = new HashMap<String, Property>(propMapCurr);
-            for (String prop : nodeProperties.keySet()) {
+            for (Map.Entry<String, Property> entry : nodeProperties.entrySet()) {
+                String prop = entry.getKey();
                 if (prop.equals(Description.propertyName)) {
                     Map<Node, Map<String, Property>> nodeProp = this.inventoryService.getNodeProps();
                     if (nodeProp.get(node) != null) {
@@ -804,8 +824,6 @@ CommandProvider {
 
     @Override
     public Status saveSwitchConfig() {
-        // Publish the save config event to the cluster nodes
-        configSaveEvent.put(new Date().getTime(), SAVE);
         return saveSwitchConfigInternal();
     }
 
@@ -880,20 +898,6 @@ CommandProvider {
         return ncList;
     }
 
-    @Override
-    public void entryCreated(Long key, String cacheName, boolean local) {
-    }
-
-    @Override
-    public void entryUpdated(Long key, String new_value, String cacheName,
-            boolean originLocal) {
-        saveSwitchConfigInternal();
-    }
-
-    @Override
-    public void entryDeleted(Long key, String cacheName, boolean originLocal) {
-    }
-
     private void addNode(Node node, Set<Property> props) {
         log.trace("{} added, props: {}", node, props);
         if (nodeProps == null) {
@@ -911,8 +915,8 @@ CommandProvider {
             }
         }
 
-        // copy node properties from config
         boolean proactiveForwarding = false;
+        // copy node properties from config
         if (nodeConfigList != null) {
             String nodeId = node.toString();
             SwitchConfig conf = nodeConfigList.get(nodeId);
@@ -926,6 +930,10 @@ CommandProvider {
             }
         }
 
+        if (!propMap.containsKey(ForwardingMode.name)) {
+            Property defaultMode = new ForwardingMode(ForwardingMode.REACTIVE_FORWARDING);
+            propMap.put(ForwardingMode.name, defaultMode);
+        }
         boolean result = false;
         if (propMapCurr == null) {
             if (nodeProps.putIfAbsent(node, propMap) == null) {
@@ -958,6 +966,17 @@ CommandProvider {
             return;
         }
         nodeProps.remove(node);
+        nodeConnectorNames.remove(node);
+        Set<NodeConnector> removeNodeConnectorSet = new HashSet<NodeConnector>();
+        for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
+            NodeConnector nodeConnector = entry.getKey();
+            if (nodeConnector.getNode().equals(node)) {
+                removeNodeConnectorSet.add(nodeConnector);
+            }
+        }
+        for (NodeConnector nc : removeNodeConnectorSet) {
+            nodeConnectorProps.remove(nc);
+        }
 
         // check if span ports need to be cleaned up
         removeSpanPorts(node);
@@ -1031,6 +1050,7 @@ CommandProvider {
     public void updateNodeConnector(NodeConnector nodeConnector,
             UpdateType type, Set<Property> props) {
         Map<String, Property> propMap = new HashMap<String, Property>();
+        boolean update = true;
 
         log.debug("updateNodeConnector: {} type {} props {} for container {}",
                 new Object[] { nodeConnector, type, props, containerName });
@@ -1041,7 +1061,6 @@ CommandProvider {
 
         switch (type) {
         case ADDED:
-        case CHANGED:
             if (props != null) {
                 for (Property prop : props) {
                     addNodeConnectorProp(nodeConnector, prop);
@@ -1053,23 +1072,39 @@ CommandProvider {
 
             addSpanPort(nodeConnector);
             break;
+        case CHANGED:
+            if (!nodeConnectorProps.containsKey(nodeConnector) || (props == null)) {
+                update = false;
+            } else {
+                for (Property prop : props) {
+                    addNodeConnectorProp(nodeConnector, prop);
+                    propMap.put(prop.getName(), prop);
+                }
+            }
+            break;
         case REMOVED:
+            if (!nodeConnectorProps.containsKey(nodeConnector)) {
+                update = false;
+            }
             removeNodeConnectorAllProps(nodeConnector);
 
             // clean up span config
             removeSpanPort(nodeConnector);
             break;
         default:
+            update = false;
             break;
         }
 
-        notifyNodeConnector(nodeConnector, type, propMap);
+        if (update) {
+            notifyNodeConnector(nodeConnector, type, propMap);
+        }
     }
 
     @Override
     public Set<Node> getNodes() {
         return (nodeProps != null) ? new HashSet<Node>(nodeProps.keySet())
-                : null;
+                : new HashSet<Node>();
     }
 
     /*
@@ -1164,7 +1199,8 @@ CommandProvider {
         }
 
         Set<NodeConnector> nodeConnectorSet = new HashSet<NodeConnector>();
-        for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
+        for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
+            NodeConnector nodeConnector = entry.getKey();
             if (!nodeConnector.getNode().equals(node)) {
                 continue;
             }
@@ -1183,7 +1219,8 @@ CommandProvider {
         }
 
         Set<NodeConnector> nodeConnectorSet = new HashSet<NodeConnector>();
-        for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
+        for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
+            NodeConnector nodeConnector = entry.getKey();
             if (!nodeConnector.getNode().equals(node)) {
                 continue;
             }
@@ -1200,7 +1237,8 @@ CommandProvider {
         }
 
         Set<NodeConnector> nodeConnectorSet = new HashSet<NodeConnector>();
-        for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
+        for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
+            NodeConnector nodeConnector = entry.getKey();
             if (!nodeConnector.getNode().equals(node)
                     || isSpecial(nodeConnector)) {
                 continue;
@@ -1339,11 +1377,12 @@ CommandProvider {
                 Map<String, NodeConnector> mapCurr = nodeConnectorNames.get(node);
                 Map<String, NodeConnector> map = new HashMap<String, NodeConnector>();
                 if (mapCurr != null) {
-                    for (String s : mapCurr.keySet()) {
+                    for (Map.Entry<String, NodeConnector> entry : mapCurr.entrySet()) {
+                        String s = entry.getKey();
                         try {
-                            map.put(s, new NodeConnector(mapCurr.get(s)));
+                            map.put(s, new NodeConnector(entry.getValue()));
                         } catch (ConstructionException e) {
-                            e.printStackTrace();
+                            log.error("An error occured",e);
                         }
                     }
                 }
@@ -1400,11 +1439,12 @@ CommandProvider {
                     Map<String, NodeConnector> mapCurr = nodeConnectorNames.get(node);
                     if (mapCurr != null) {
                         Map<String, NodeConnector> map = new HashMap<String, NodeConnector>();
-                        for (String s : mapCurr.keySet()) {
+                        for (Map.Entry<String, NodeConnector> entry : mapCurr.entrySet()) {
+                            String s = entry.getKey();
                             try {
-                                map.put(s, new NodeConnector(mapCurr.get(s)));
+                                map.put(s, new NodeConnector(entry.getValue()));
                             } catch (ConstructionException e) {
-                                e.printStackTrace();
+                                log.error("An error occured",e);
                             }
                         }
                         map.remove(name.getValue());
@@ -1436,17 +1476,22 @@ CommandProvider {
                 Map<String, NodeConnector> mapCurr = nodeConnectorNames.get(node);
                 if (mapCurr != null) {
                     Map<String, NodeConnector> map = new HashMap<String, NodeConnector>();
-                    for (String s : mapCurr.keySet()) {
+                    for (Map.Entry<String, NodeConnector> entry : mapCurr.entrySet()) {
+                        String s = entry.getKey();
                         try {
-                            map.put(s, new NodeConnector(mapCurr.get(s)));
+                            map.put(s, new NodeConnector(entry.getValue()));
                         } catch (ConstructionException e) {
-                            e.printStackTrace();
+                            log.error("An error occured",e);
                         }
                     }
                     map.remove(name.getValue());
-                    if (!nodeConnectorNames.replace(node, mapCurr, map)) {
-                        log.warn("Cluster conflict: Unable remove Name property of nodeconnector {}, skip.",
-                                nodeConnector.getID());
+                    if (map.isEmpty()) {
+                        nodeConnectorNames.remove(node);
+                    } else {
+                        if (!nodeConnectorNames.replace(node, mapCurr, map)) {
+                            log.warn("Cluster conflict: Unable remove Name property of nodeconnector {}, skip.",
+                                    nodeConnector.getID());
+                        }
                     }
                 }
 
@@ -1530,6 +1575,16 @@ CommandProvider {
         clearInventories();
     }
 
+    public void setStatisticsManager(IStatisticsManager statisticsManager) {
+        log.trace("Got statistics manager set request {}", statisticsManager);
+        this.statisticsManager = statisticsManager;
+    }
+
+    public void unsetStatisticsManager(IStatisticsManager statisticsManager) {
+        log.trace("Got statistics manager UNset request");
+        this.statisticsManager = null;
+    }
+
     public void setSwitchManagerAware(ISwitchManagerAware service) {
         log.trace("Got inventory service set request {}", service);
         if (this.switchManagerAware != null) {
@@ -1671,7 +1726,8 @@ CommandProvider {
             service.notifyNode(node, type, propMap);
         }
 
-        for (NodeConnector nodeConnector : nodeConnectorProps.keySet()) {
+        for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
+            NodeConnector nodeConnector = entry.getKey();
             propMap = nodeConnectorProps.get(nodeConnector);
             service.notifyNodeConnector(nodeConnector, type, propMap);
         }
@@ -1710,8 +1766,6 @@ CommandProvider {
     public String getHelp() {
         StringBuffer help = new StringBuffer();
         help.append("---Switch Manager---\n");
-        help.append("\t pns                    - Print connected nodes\n");
-        help.append("\t pncs <node id>         - Print node connectors for a given node\n");
         help.append("\t pencs <node id>        - Print enabled node connectors for a given node\n");
         help.append("\t pdm <node id>          - Print switch ports in device map\n");
         help.append("\t snt <node id> <tier>   - Set node tier number\n");
@@ -1720,37 +1774,6 @@ CommandProvider {
         return help.toString();
     }
 
-    public void _pns(CommandInterpreter ci) {
-        ci.println("           Node               Type           MAC            Name      Tier");
-        if (nodeProps == null) {
-            return;
-        }
-        Set<Node> nodeSet = nodeProps.keySet();
-        if (nodeSet == null) {
-            return;
-        }
-        List<String> nodeArray = new ArrayList<String>();
-        for (Node node : nodeSet) {
-            nodeArray.add(node.toString());
-        }
-        Collections.sort(nodeArray);
-        for (String str: nodeArray) {
-            Node node = Node.fromString(str);
-            Description desc = ((Description) getNodeProp(node,
-                    Description.propertyName));
-            Tier tier = ((Tier) getNodeProp(node, Tier.TierPropName));
-            String nodeName = (desc == null) ? "" : desc.getValue();
-            MacAddress mac = (MacAddress) getNodeProp(node,
-                    MacAddress.name);
-            String macAddr = (mac == null) ? "" : HexEncode
-                    .bytesToHexStringFormat(mac.getMacAddress());
-            int tierNum = (tier == null) ? 0 : tier.getValue();
-            ci.println(node + "     " + node.getType() + "     " + macAddr
-                    + "     " + nodeName + "     " + tierNum);
-        }
-        ci.println("Total number of Nodes: " + nodeSet.size());
-    }
-
     public void _pencs(CommandInterpreter ci) {
         String st = ci.nextArgument();
         if (st == null) {
@@ -1777,43 +1800,6 @@ CommandProvider {
         ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
     }
 
-    public void _pncs(CommandInterpreter ci) {
-        String st = ci.nextArgument();
-        if (st == null) {
-            ci.println("Please enter node id");
-            return;
-        }
-
-        Node node = Node.fromString(st);
-        if (node == null) {
-            ci.println("Please enter node id");
-            return;
-        }
-
-        ci.println("          NodeConnector               BandWidth(Gbps)     Admin     State");
-        Set<NodeConnector> nodeConnectorSet = getNodeConnectors(node);
-        if (nodeConnectorSet == null) {
-            return;
-        }
-        for (NodeConnector nodeConnector : nodeConnectorSet) {
-            if (nodeConnector == null) {
-                continue;
-            }
-            Map<String, Property> propMap = getNodeConnectorProps(nodeConnector);
-            Bandwidth bw = (Bandwidth) propMap.get(Bandwidth.BandwidthPropName);
-            Config config = (Config) propMap.get(Config.ConfigPropName);
-            State state = (State) propMap.get(State.StatePropName);
-            String out = nodeConnector + "           ";
-            out += (bw != null) ? bw.getValue() / Math.pow(10, 9) : "    ";
-            out += "             ";
-            out += (config != null) ? config.getValue() : " ";
-            out += "          ";
-            out += (state != null) ? state.getValue() : " ";
-            ci.println(out);
-        }
-        ci.println("Total number of NodeConnectors: " + nodeConnectorSet.size());
-    }
-
     public void _pdm(CommandInterpreter ci) {
         String st = ci.nextArgument();
         if (st == null) {
@@ -2022,12 +2008,6 @@ CommandProvider {
         nodeProps.put(node, propMap);
     }
 
-    private void removeNodeProps(Node node) {
-        if (getUpNodeConnectors(node).size() == 0) {
-            nodeProps.remove(node);
-        }
-    }
-
     @Override
     public Status saveConfiguration() {
         return saveSwitchConfig();