Fix occasional NPEs in Connection manager 88/1388/1
authorYevgeny Khodorkovsky <ykhodork@cisco.com>
Mon, 16 Sep 2013 18:02:03 +0000 (11:02 -0700)
committerYevgeny Khodorkovsky <ykhodork@cisco.com>
Tue, 24 Sep 2013 02:29:21 +0000 (19:29 -0700)
- This fixes an issue where ConnectionManager bundle start/stop
  callbacks don't have the required dependenicies available, which
  causes occasional NPEs.

Change-Id: I3f9f17a4a500915cf72419bb352a40233506b846
Signed-off-by: Yevgeny Khodorkovsky <ykhodork@cisco.com>
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/internal/ConnectionManager.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AbstractScheme.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/AnyControllerScheme.java
opendaylight/connectionmanager/implementation/src/main/java/org/opendaylight/controller/connectionmanager/scheme/SingleControllerScheme.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/InventoryServiceShim.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/internal/OFStatisticsManager.java
opendaylight/switchmanager/implementation/src/main/java/org/opendaylight/controller/switchmanager/internal/SwitchManager.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWeb.java

index df5175083b1870ef99b29443d42003eb2bb179c5..2d5f80fb79f99365544680e77df45cb779f897d9 100644 (file)
@@ -30,8 +30,6 @@ import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.LinkedBlockingQueue;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.eclipse.osgi.framework.console.CommandInterpreter;
 import org.eclipse.osgi.framework.console.CommandProvider;
 import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
@@ -55,6 +53,8 @@ import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ConnectionManager implements IConnectionManager, IConnectionListener,
                                           ICoordinatorChangeAware, IListenInventoryUpdates,
@@ -123,8 +123,19 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene
         }
     }
 
-    public void started() {
-        connectionEventThread = new Thread(new EventHandler(), "ConnectionEvent Thread");
+
+   public void started() {
+       String schemeStr = System.getProperty("connection.scheme");
+       for (ConnectionMgmtScheme scheme : ConnectionMgmtScheme.values()) {
+           AbstractScheme schemeImpl = SchemeFactory.getScheme(scheme, clusterServices);
+           if (schemeImpl != null) {
+               schemes.put(scheme, schemeImpl);
+               if (scheme.name().equalsIgnoreCase(schemeStr)) {
+                   activeScheme = scheme;
+               }
+           }
+       }
+
         connectionEventThread.start();
 
         registerWithOSGIConsole();
@@ -134,21 +145,12 @@ public class ConnectionManager implements IConnectionManager, IConnectionListene
     }
 
     public void init() {
-        String schemeStr = System.getProperty("connection.scheme");
+        connectionEventThread = new Thread(new EventHandler(), "ConnectionEvent Thread");
         this.connectionEvents = new LinkedBlockingQueue<ConnectionMgmtEvent>();
         schemes = new ConcurrentHashMap<ConnectionMgmtScheme, AbstractScheme>();
-        for (ConnectionMgmtScheme scheme : ConnectionMgmtScheme.values()) {
-            AbstractScheme schemeImpl = SchemeFactory.getScheme(scheme, clusterServices);
-            if (schemeImpl != null) {
-                schemes.put(scheme, schemeImpl);
-                if (scheme.name().equalsIgnoreCase(schemeStr)) {
-                    activeScheme = scheme;
-                }
-            }
-        }
     }
 
-    public void stop() {
+    public void stopping() {
         connectionEventThread.interrupt();
         Set<Node> localNodes = getLocalNodes();
         if (localNodes != null) {
index 78f274c717585993d13a3deeb86812a32ad4ad5a..062fd1ee777564aa1a90863e3826ef7648e12454 100644 (file)
@@ -35,15 +35,18 @@ public abstract class AbstractScheme {
      */
     protected ConcurrentMap <Node, Set<InetAddress>> nodeConnections;
     protected abstract boolean isConnectionAllowedInternal(Node node);
-    private String name;
+    private final String name;
+    private final String nodeConnectionsCacheName;
 
     protected AbstractScheme(IClusterGlobalServices clusterServices, ConnectionMgmtScheme type) {
         this.clusterServices = clusterServices;
-        if (type != null) name = type.name();
-        else name = "UNKNOWN";
+        name = (type != null ? type.name() : "UNKNOWN");
+        nodeConnectionsCacheName = "connectionmanager."+name+".nodeconnections";
         if (clusterServices != null) {
             allocateCaches();
             retrieveCaches();
+        } else {
+            log.error("Couldn't retrieve caches for scheme %s. Clustering service unavailable", name);
         }
     }
 
@@ -72,7 +75,6 @@ public abstract class AbstractScheme {
         return isConnectionAllowedInternal(node);
     }
 
-    @SuppressWarnings("deprecation")
     public void handleClusterViewChanged() {
         log.debug("Handling Cluster View changed notification");
         List<InetAddress> controllers = clusterServices.getClusteredControllers();
@@ -122,7 +124,6 @@ public abstract class AbstractScheme {
     }
 
     public Set<Node> getNodes(InetAddress controller) {
-        if (nodeConnections == null) return null;
         ConcurrentMap <InetAddress, Set<Node>> controllerNodesMap = getControllerToNodesMap();
         return controllerNodesMap.get(controller);
     }
@@ -162,7 +163,7 @@ public abstract class AbstractScheme {
 
     protected Status removeNodeFromController (Node node, InetAddress controller) {
         if (node == null || controller == null) {
-            return new Status(StatusCode.BADREQUEST);
+            return new Status(StatusCode.BADREQUEST, "Invalid Node or Controller Address Specified.");
         }
 
         if (clusterServices == null || nodeConnections == null) {
@@ -189,7 +190,7 @@ public abstract class AbstractScheme {
                     }
                     clusterServices.tcommit();
                 } catch (Exception e) {
-                    log.error("Excepion in removing Controller from a Node", e);
+                    log.error("Exception in removing Controller from a Node", e);
                     try {
                         clusterServices.trollback();
                     } catch (Exception e1) {
@@ -210,7 +211,7 @@ public abstract class AbstractScheme {
      */
     private Status putNodeToController (Node node, InetAddress controller) {
         if (clusterServices == null || nodeConnections == null) {
-            return new Status(StatusCode.SUCCESS);
+            return new Status(StatusCode.INTERNALERROR, "Cluster service unavailable, or node connections info missing.");
         }
         log.debug("Trying to Put {} to {}", controller.getHostAddress(), node.toString());
 
@@ -277,7 +278,9 @@ public abstract class AbstractScheme {
         if (node == null || controller == null) {
             return new Status(StatusCode.BADREQUEST);
         }
-        if (isLocal(node)) return new Status(StatusCode.SUCCESS);
+        if (isLocal(node))  {
+            return new Status(StatusCode.SUCCESS);
+        }
         if (isConnectionAllowed(node)) {
             return putNodeToController(node, controller);
         } else {
@@ -285,36 +288,34 @@ public abstract class AbstractScheme {
         }
     }
 
-    @SuppressWarnings("deprecation")
     public Status addNode (Node node) {
         return addNode(node, clusterServices.getMyAddress());
     }
 
-    @SuppressWarnings({ "unchecked", "deprecation" })
+    @SuppressWarnings({ "unchecked" })
     private void retrieveCaches() {
         if (this.clusterServices == null) {
-            log.error("un-initialized clusterServices, can't retrieve cache");
+            log.error("Un-initialized Cluster Services, can't retrieve caches for scheme: {}", name);
             return;
         }
 
-        nodeConnections = (ConcurrentMap<Node, Set<InetAddress>>) clusterServices.getCache("connectionmanager."+name+".nodeconnections");
+        nodeConnections = (ConcurrentMap<Node, Set<InetAddress>>) clusterServices.getCache(nodeConnectionsCacheName);
 
         if (nodeConnections == null) {
-            log.error("\nFailed to get caches");
+            log.error("\nFailed to get cache: {}", nodeConnectionsCacheName);
         }
     }
 
-    @SuppressWarnings("deprecation")
     private void allocateCaches() {
         if (this.clusterServices == null) {
-            log.error("un-initialized clusterServices, can't create cache");
+            log.error("Un-initialized clusterServices, can't create cache");
             return;
         }
 
         try {
-            clusterServices.createCache("connectionmanager."+name+".nodeconnections", EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
+            clusterServices.createCache(nodeConnectionsCacheName, EnumSet.of(IClusterServices.cacheMode.TRANSACTIONAL));
         } catch (CacheExistException cee) {
-            log.error("\nCache already exists - destroy and recreate if needed");
+            log.debug("\nCache already exists: {}", nodeConnectionsCacheName);
         } catch (CacheConfigException cce) {
             log.error("\nCache configuration invalid - check cache mode");
         } catch (Exception e) {
index 02282c30808be5a7ae673d1cd8227615c2ec3c1c..4db64a64d315a1ceab0d3146c571baf66379bf55 100644 (file)
@@ -2,14 +2,12 @@ package org.opendaylight.controller.connectionmanager.scheme;
 
 import java.net.InetAddress;
 import java.util.Set;
+
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
 import org.opendaylight.controller.connectionmanager.ConnectionMgmtScheme;
 import org.opendaylight.controller.sal.core.Node;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 class AnyControllerScheme extends AbstractScheme {
-    private static final Logger logger = LoggerFactory.getLogger(AnyControllerScheme.class);
     private static AbstractScheme myScheme= null;
 
     protected AnyControllerScheme(IClusterGlobalServices clusterServices) {
@@ -23,10 +21,8 @@ class AnyControllerScheme extends AbstractScheme {
         return myScheme;
     }
 
-    @SuppressWarnings("deprecation")
     @Override
     public boolean isConnectionAllowedInternal(Node node) {
-        if (nodeConnections == null) return true;
         Set <InetAddress> controllers = nodeConnections.get(node);
         if (controllers == null || controllers.size() == 0) return true;
         return (controllers.size() == 1 && controllers.contains(clusterServices.getMyAddress()));
index 6afb27fb9ef5fbc5c345616c01af97f624084755..a84a11b33614d2b7ffce0d3fba3b839fe35749f4 100644 (file)
@@ -6,7 +6,7 @@ import org.opendaylight.controller.sal.core.Node;
 
 class SingleControllerScheme extends AbstractScheme {
 
-    private static AbstractScheme myScheme= null;
+    private static AbstractScheme myScheme = null;
 
     protected SingleControllerScheme(IClusterGlobalServices clusterServices) {
         super(clusterServices, ConnectionMgmtScheme.SINGLE_CONTROLLER);
@@ -19,12 +19,9 @@ class SingleControllerScheme extends AbstractScheme {
         return myScheme;
     }
 
-    @SuppressWarnings("deprecation")
     @Override
     public boolean isConnectionAllowedInternal(Node node) {
-        if (nodeConnections == null) return true;
         // Lets make it simple. The Cluster Coordinator is the master
-        if (clusterServices.amICoordinator()) return true;
-        return false;
+        return clusterServices.amICoordinator();
     }
 }
\ No newline at end of file
index 15bba670d2a7b9e4387317e91f12e50e18cb5e29..6401ec52f81faba1694302314882affb0d818ca5 100644 (file)
@@ -255,8 +255,7 @@ public class InventoryServiceShim implements IContainerListener,
                 props.addAll(prop);
             }
             nodeConnectorProps.put(entry.getKey(), props);
-            notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED,
-                    entry.getValue());
+            notifyInventoryShimListener(entry.getKey(), UpdateType.ADDED, entry.getValue());
         }
 
         // Add this node
@@ -357,15 +356,13 @@ public class InventoryServiceShim implements IContainerListener,
         }
     }
 
-    private void notifyInventoryShimExternalListener(Node node,
-            UpdateType type, Set<Property> props) {
+    private void notifyInventoryShimExternalListener(Node node, UpdateType type, Set<Property> props) {
         for (IInventoryShimExternalListener s : this.inventoryShimExternalListeners) {
             s.updateNode(node, type, props);
         }
     }
 
-    private void notifyInventoryShimExternalListener(
-            NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
+    private void notifyInventoryShimExternalListener(NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
         for (IInventoryShimExternalListener s : this.inventoryShimExternalListeners) {
             s.updateNodeConnector(nodeConnector, type, props);
         }
@@ -373,14 +370,11 @@ public class InventoryServiceShim implements IContainerListener,
 
     private void notifyInventoryShimInternalListener(String container,
             NodeConnector nodeConnector, UpdateType type, Set<Property> props) {
-        IInventoryShimInternalListener inventoryShimInternalListener = inventoryShimInternalListeners
-                .get(container);
+        IInventoryShimInternalListener inventoryShimInternalListener = inventoryShimInternalListeners.get(container);
         if (inventoryShimInternalListener != null) {
-            inventoryShimInternalListener.updateNodeConnector(nodeConnector,
-                    type, props);
-            logger.trace(
-                    "notifyInventoryShimInternalListener {} type {} for container {}",
-                    new Object[] { nodeConnector, type, container });
+            inventoryShimInternalListener.updateNodeConnector(nodeConnector, type, props);
+            logger.trace("notifyInventoryShimInternalListener {} type {} for container {}", new Object[] {
+                    nodeConnector, type, container });
         }
     }
 
@@ -409,7 +403,7 @@ public class InventoryServiceShim implements IContainerListener,
                 notifyInventoryShimInternalListener(container, nodeConnector, type, props);
             }
 
-            // Notify DiscoveryService
+            // Notify plugin listeners (Discovery, DataPacket, OFstats etc.)
             notifyInventoryShimExternalListener(nodeConnector, type, props);
 
             logger.debug("Connection service accepted the inventory notification for {} {}", nodeConnector, type);
@@ -436,13 +430,14 @@ public class InventoryServiceShim implements IContainerListener,
 
         if (isNodeLocal) {
             // Now notify other containers
-            Set<String> containers = (nodeContainerMap.get(node) == null) ? new HashSet<String>() : new HashSet<String>(
-                    nodeContainerMap.get(node));
+            Set<String> containers = (nodeContainerMap.get(node) == null) ? new HashSet<String>()
+                    : new HashSet<String>(nodeContainerMap.get(node));
             containers.add(GlobalConstants.DEFAULT.toString());
             for (String container : containers) {
                 notifyInventoryShimInternalListener(container, node, type, props);
             }
-            // Notify external listener
+
+            // Notify plugin listeners (Discovery, DataPacket, OFstats etc.)
             notifyInventoryShimExternalListener(node, type, props);
 
             logger.debug("Connection service accepted the inventory notification for {} {}", node, type);
@@ -454,9 +449,7 @@ public class InventoryServiceShim implements IContainerListener,
     private void notifyGlobalInventoryShimInternalListener(Node node, UpdateType type, Set<Property> props) {
         for (IInventoryShimInternalListener globalListener : globalInventoryShimInternalListeners) {
             globalListener.updateNode(node, type, props);
-            logger.trace(
-                    "notifyGlobalInventoryShimInternalListener {} type {}",
-                    new Object[] { node, type });
+            logger.trace("notifyGlobalInventoryShimInternalListener {} type {}", new Object[] { node, type });
         }
     }
 
index 3ab38cc41f6db686b273864801c238f3cb36eb11..48b46eac85b9fc467387fc6454e21bb156d74796 100644 (file)
@@ -63,12 +63,11 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * It periodically polls the different OF statistics from the OF switches and
- * caches them for quick retrieval for the above layers' modules It also
- * provides an API to directly query the switch about the statistics
+ * Periodically polls the different OF statistics from the OF switches, caches
+ * them, and publishes results towards SAL. It also provides an API to directly
+ * query the switch for any specific statistics.
  */
-public class OFStatisticsManager implements IOFStatisticsManager,
-IInventoryShimExternalListener, CommandProvider {
+public class OFStatisticsManager implements IOFStatisticsManager, IInventoryShimExternalListener, CommandProvider {
     private static final Logger log = LoggerFactory.getLogger(OFStatisticsManager.class);
     private static final int INITIAL_SIZE = 64;
     private static final long FLOW_STATS_PERIOD = 10000;
index 49cdabfeb3055a3f8a3a35237ec1e6168f84d09e..0581aa49ea574a214faf2c78acfbf9ecb449ceb1 100644 (file)
@@ -414,9 +414,8 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
         }
         for (InetAddress i : IPs) {
             Subnet existingSubnet = subnets.get(i);
-            if ((existingSubnet != null)
-                    && !existingSubnet.isMutualExclusive(newSubnet)) {
-                return new Status(StatusCode.CONFLICT);
+            if ((existingSubnet != null) && !existingSubnet.isMutualExclusive(newSubnet)) {
+                return new Status(StatusCode.CONFLICT, "This subnet conflicts with an existing one.");
             }
         }
         return new Status(StatusCode.SUCCESS);
@@ -434,7 +433,7 @@ public class SwitchManager implements ISwitchManager, IConfigurationContainerAwa
             // Presence check
             if (subnetsConfigList.containsKey(conf.getName())) {
                 return new Status(StatusCode.CONFLICT,
-                        "Subnet with the specified name already configured.");
+                        "Subnet with the specified name already exists.");
             }
             // Semantic check
             status = semanticCheck(conf);
index 24f0b4d80c77eb52cbff414f1900614b0521eaac..78f4b5449760e09f9d752e7477b53b49c16f10a7 100644 (file)
@@ -100,8 +100,7 @@ public class DaylightWeb {
     }
 
     @RequestMapping(value = "logout")
-    public String login(Map<String, Object> model,
-            final HttpServletRequest request) {
+    public String logout(Map<String, Object> model, final HttpServletRequest request) {
 
         IUserManager userManager = (IUserManager) ServiceHelper
                 .getGlobalInstance(IUserManager.class, this);