Node Name in non-default container should default to Node Name in Default Slice
[controller.git] / opendaylight / switchmanager / implementation / src / main / java / org / opendaylight / controller / switchmanager / internal / SwitchManager.java
index 770180c04e7ae754e91d12659ae43ea2577a3d4b..8372f88e7dce895e135debf1daef17e18d02b0f1 100644 (file)
@@ -12,13 +12,10 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.SocketException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Dictionary;
 import java.util.EnumSet;
-import java.util.Enumeration;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -56,8 +53,8 @@ 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;
+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.statisticsmanager.IStatisticsManager;
@@ -102,6 +99,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     private ConcurrentMap<String, Property> controllerProps;
     private IInventoryService inventoryService;
     private IStatisticsManager statisticsManager;
+    private IControllerProperties controllerProperties;
     private IConfigurationContainerService configurationService;
     private final Set<ISwitchManagerAware> switchManagerAware = Collections
             .synchronizedSet(new HashSet<ISwitchManagerAware>());
@@ -118,6 +116,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
      * only subnet returned. As soon as a user-configured subnet is created this one will
      * vanish.
      */
+    private static final String DISABLE_DEFAULT_SUBNET_PROP = "switchmanager.disableDefaultSubnetGateway";
+    private static final String DISABLE_DEFAULT_SUBNET_PROP_VAL = System.getProperty(DISABLE_DEFAULT_SUBNET_PROP);
+    private static final boolean USE_DEFAULT_SUBNET_GW = !Boolean.valueOf(DISABLE_DEFAULT_SUBNET_PROP_VAL);
     protected static final SubnetConfig DEFAULT_SUBNETCONFIG;
     protected static final Subnet DEFAULT_SUBNET;
     protected static final String DEFAULT_SUBNET_NAME = "default (cannot be modifed)";
@@ -171,13 +172,13 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         retrieveCaches();
 
         // Add controller MAC, if first node in the cluster
-        if (!controllerProps.containsKey(MacAddress.name)) {
-            byte controllerMac[] = getHardwareMAC();
+        if ((!controllerProps.containsKey(MacAddress.name)) && (controllerProperties != null)) {
+            Property controllerMac = controllerProperties.getControllerProperty(MacAddress.name);
             if (controllerMac != null) {
-                Property existing = controllerProps.putIfAbsent(MacAddress.name, new MacAddress(controllerMac));
+                Property existing = controllerProps.putIfAbsent(MacAddress.name, controllerMac);
                 if (existing == null && log.isTraceEnabled()) {
                     log.trace("Container {}: Setting controller MAC address in the cluster: {}", getContainerName(),
-                            HexEncode.bytesToHexStringFormat(controllerMac));
+                            controllerMac);
                 }
             }
         }
@@ -291,9 +292,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     @Override
     public List<SubnetConfig> getSubnetsConfigList() {
         // if there are no subnets, return the default subnet
-        if(subnetsConfigList.size() == 0){
+        if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty()) {
             return Collections.singletonList(DEFAULT_SUBNETCONFIG);
-        }else{
+        } else {
             return new ArrayList<SubnetConfig>(subnetsConfigList.values());
         }
     }
@@ -301,9 +302,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     @Override
     public SubnetConfig getSubnetConfig(String subnet) {
         // if there are no subnets, return the default subnet
-        if(subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)){
+        if (USE_DEFAULT_SUBNET_GW && subnetsConfigList.isEmpty() && subnet.equalsIgnoreCase(DEFAULT_SUBNET_NAME)) {
             return DEFAULT_SUBNETCONFIG;
-        }else{
+        } else {
             return subnetsConfigList.get(subnet);
         }
     }
@@ -839,9 +840,14 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
             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);
+                    if (advertisedDesc != null) {
+                        if (!advertisedDesc.isEmpty()) {
+                            Property desc = new Description(advertisedDesc);
+                            propMap.put(Description.propertyName, desc);
+                        }
+                    }
+                    else {
+                        propMap.remove(prop);
                     }
                     continue;
                 } else if (prop.equals(ForwardingMode.name)) {
@@ -999,7 +1005,8 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
             }
         }
 
-        boolean proactiveForwarding = false;
+        boolean forwardingModeChanged = false;
+
         // copy node properties from config
         if (nodeConfigList != null) {
             String nodeId = node.toString();
@@ -1009,7 +1016,19 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
                 propMap.putAll(nodeProperties);
                 if (nodeProperties.get(ForwardingMode.name) != null) {
                     ForwardingMode mode = (ForwardingMode) nodeProperties.get(ForwardingMode.name);
-                    proactiveForwarding = mode.isProactive();
+                    forwardingModeChanged = mode.isProactive();
+                }
+            } else if ((conf == null) &&  !(GlobalConstants.DEFAULT.toString().equals(containerName))) {
+                ISwitchManager defaultSwitchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, GlobalConstants.DEFAULT.toString(), this);
+                if (defaultSwitchManager != null) {
+                    Property defaultContainerSwitchDesc = (Description) defaultSwitchManager.getNodeProp(node, Description.propertyName);
+                    if (defaultContainerSwitchDesc != null) {
+                        Map<String, Property> descPropMap = new HashMap<String, Property>();
+                        descPropMap.put(Description.propertyName, defaultContainerSwitchDesc);
+                        conf = new SwitchConfig(nodeId, descPropMap);
+                        updateNodeConfig(conf);
+                        propMap.put(Description.propertyName, defaultContainerSwitchDesc);
+                    }
                 }
             }
         }
@@ -1018,28 +1037,35 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
             Property defaultMode = new ForwardingMode(ForwardingMode.REACTIVE_FORWARDING);
             propMap.put(ForwardingMode.name, defaultMode);
         }
-        boolean result = false;
-        if (propMapCurr == null) {
-            if (nodeProps.putIfAbsent(node, propMap) == null) {
-                result = true;
-            }
+
+        boolean propsAdded = false;
+        // Attempt initial add
+        if (nodeProps.putIfAbsent(node, propMap) == null) {
+                propsAdded = true;
+
+                /* Notify listeners only for initial node addition
+                 * to avoid expensive tasks triggered by redundant notifications
+                 */
+                notifyNode(node, UpdateType.ADDED, propMap);
         } else {
-            result = nodeProps.replace(node, propMapCurr, propMap);
+
+            propsAdded = nodeProps.replace(node, propMapCurr, propMap);
+
+            // check whether forwarding mode changed
+            if (propMapCurr.get(ForwardingMode.name) != null) {
+                ForwardingMode mode = (ForwardingMode) propMapCurr.get(ForwardingMode.name);
+                forwardingModeChanged ^= mode.isProactive();
+            }
         }
-        if (!result) {
-            log.debug("Cluster conflict: Conflict while adding the node properties. Node: {}  Properties: {}",
-                    node.getID(), props);
+        if (!propsAdded) {
+            log.debug("Cluster conflict while adding node {}. Overwriting with latest props: {}", node.getID(), props);
             addNodeProps(node, propMap);
         }
 
-        // check if span ports are configed
+        // check if span ports are configured
         addSpanPorts(node);
-
-        // notify node listeners
-        notifyNode(node, UpdateType.ADDED, propMap);
-
         // notify proactive mode forwarding
-        if (proactiveForwarding) {
+        if (forwardingModeChanged) {
             notifyModeChange(node, true);
         }
     }
@@ -1049,7 +1075,12 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         if (nodeProps == null) {
             return;
         }
-        nodeProps.remove(node);
+
+        if (nodeProps.remove(node) == null) {
+            log.debug("Received redundant node REMOVED udate for {}. Skipping..", node);
+            return;
+        }
+
         nodeConnectorNames.remove(node);
         Set<NodeConnector> removeNodeConnectorSet = new HashSet<NodeConnector>();
         for (Map.Entry<NodeConnector, Map<String, Property>> entry : nodeConnectorProps.entrySet()) {
@@ -1144,6 +1175,13 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
 
         switch (type) {
         case ADDED:
+            // Skip redundant ADDED update (e.g. cluster switch-over)
+            if (nodeConnectorProps.containsKey(nodeConnector)) {
+                log.debug("Redundant nodeconnector ADDED for {}, props {} for container {}",
+                        nodeConnector, props, containerName);
+                update = false;
+            }
+
             if (props != null) {
                 for (Property prop : props) {
                     addNodeConnectorProp(nodeConnector, prop);
@@ -1153,6 +1191,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
                 addNodeConnectorProp(nodeConnector, null);
             }
 
+
             addSpanPort(nodeConnector);
             break;
         case CHANGED:
@@ -1379,36 +1418,6 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         return (propMap != null) ? propMap.get(propName) : null;
     }
 
-    private byte[] getHardwareMAC() {
-        Enumeration<NetworkInterface> nis;
-        byte[] macAddress = null;
-
-        try {
-            nis = NetworkInterface.getNetworkInterfaces();
-        } catch (SocketException e) {
-            log.error("Failed to acquire controller MAC: ", e);
-            return macAddress;
-        }
-
-        while (nis.hasMoreElements()) {
-            NetworkInterface ni = nis.nextElement();
-            try {
-                macAddress = ni.getHardwareAddress();
-            } catch (SocketException e) {
-                log.error("Failed to acquire controller MAC: ", e);
-            }
-            if (macAddress != null) {
-                break;
-            }
-        }
-        if (macAddress == null) {
-            log.warn("Failed to acquire controller MAC: No physical interface found");
-            // This happens when running controller on windows VM, for example
-            // Try parsing the OS command output
-        }
-        return macAddress;
-    }
-
     @Override
     public byte[] getControllerMAC() {
         MacAddress macProperty = (MacAddress)controllerProps.get(MacAddress.name);
@@ -1767,6 +1776,16 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         }
     }
 
+    public void setControllerProperties(IControllerProperties controllerProperties) {
+        log.trace("Got controller properties set request {}", controllerProperties);
+        this.controllerProperties = controllerProperties;
+    }
+
+    public void unsetControllerProperties(IControllerProperties controllerProperties) {
+        log.trace("Got controller properties UNset request");
+        this.controllerProperties = null;
+    }
+
     private void getInventories() {
         if (inventoryService == null) {
             log.trace("inventory service not avaiable");
@@ -2021,9 +2040,9 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         // only add if span is configured on this nodeConnector
         for (SpanConfig conf : getSpanConfigList(nodeConnector.getNode())) {
             if (conf.getPortArrayList().contains(nodeConnector)) {
-                List<NodeConnector> ncLists = new ArrayList<NodeConnector>();
-                ncLists.add(nodeConnector);
-                addSpanPorts(nodeConnector.getNode(), ncLists);
+                List<NodeConnector> ncList = new ArrayList<NodeConnector>();
+                ncList.add(nodeConnector);
+                addSpanPorts(nodeConnector.getNode(), ncList);
                 return;
             }
         }
@@ -2144,7 +2163,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
     public Set<Switch> getConfiguredNotConnectedSwitches() {
         Set<Switch> configuredNotConnectedSwitches = new HashSet<Switch>();
         if (this.inventoryService == null) {
-            log.trace("inventory service not avaiable");
+            log.trace("inventory service not available");
             return configuredNotConnectedSwitches;
         }