Merge "simple JUnit test for switchmanager.northbound Signed-off-by: Kalvin Hom ...
authorBhushan Kanekar <bkanekar@cisco.com>
Thu, 28 Mar 2013 01:10:50 +0000 (01:10 +0000)
committerGerrit Code Review <gerrit@daylight1.linux-foundation.org>
Thu, 28 Mar 2013 01:10:50 +0000 (01:10 +0000)
18 files changed:
opendaylight/forwardingrulesmanager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/IForwardingRulesManager.java
opendaylight/forwardingrulesmanager/src/main/java/org/opendaylight/controller/forwardingrulesmanager/internal/ForwardingRulesManagerImpl.java
opendaylight/northbound/flowprogrammer/src/main/java/org/opendaylight/controller/flowprogrammer/northbound/FlowProgrammerNorthbound.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/Controller.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/ControllerIO.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/core/internal/SwitchHandler.java
opendaylight/routing/dijkstra_implementation/pom.xml
opendaylight/routing/dijkstra_implementation/src/main/java/org/opendaylight/controller/routing/dijkstra_implementation/internal/Activator.java
opendaylight/routing/dijkstra_implementation/src/main/java/org/opendaylight/controller/routing/dijkstra_implementation/internal/DijkstraImplementation.java
opendaylight/routing/dijkstra_implementation/src/test/java/org/opendaylight/controller/routing/dijkstra_implementation/DijkstraTest.java
opendaylight/routing/dijkstra_implementation/src/test/java/org/opendaylight/controller/routing/dijkstra_implementation/MaxThruputTest.java
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BindingBrokerImpl.java
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationInvoker.java
opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/NotificationModule.java
opendaylight/sal/yang-prototype/sal/sal-core-api/src/main/java/org/opendaylight/controller/sal/core/api/notify/NotificationProviderService.java
opendaylight/topologymanager/src/main/java/org/opendaylight/controller/topologymanager/internal/TopologyManagerImpl.java
opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java

index 3a1250becfbdc1ac6d23aea3228d997fc6ead7ac..60d74295ee4ff0542f87cecd225d46d4d61d8bdd 100644 (file)
@@ -255,6 +255,17 @@ public interface IForwardingRulesManager {
      * @return the {@code Status} object indicating the result of this action
      */
     public Status toggleStaticFlowStatus(FlowConfig configObject);
+    
+    /**
+     * Toggle the installation status of the specified configured flow
+     * If the flow configuration status is active, this call will
+     * change the flow status to inactive and vice-versa
+     *
+     * @param name for the static flow
+     * @param node on which the flow is attached
+     * @return the {@code Status} object indicating the result of this action
+     */
+    public Status toggleStaticFlowStatus(String name, Node node);
 
     public Map<String, PortGroupConfig> getPortGroupConfigs();
 
index 08d34127a5a58107b731ad6c6cc666853d30c478..bdaae5b28ce40245a43e040b1d46e13963c11277 100644 (file)
@@ -1451,8 +1451,20 @@ public class ForwardingRulesManagerImpl implements IForwardingRulesManager,
         return status;
     }
 
+
+
+       @Override
+       public Status toggleStaticFlowStatus(String name, Node node) {
+               return toggleStaticFlowStatus(getStaticFlow(name, node));
+       }
+       
     @Override
     public Status toggleStaticFlowStatus(FlowConfig config) {
+       if (config == null) {
+               String msg = "Invalid request: null flow config";
+               log.warn(msg);
+               return new Status(StatusCode.BADREQUEST, msg);
+       }
         // Validity check for api3 entry point
         if (config.isInternalFlow()) {
                String msg = "Invalid operation: Controller generated flow " +
index e4ca83a260903d9fd808cae8901daaa2239820a7..ed3abde0ab22bc84049f3f8787436d5a775a8fda 100644 (file)
@@ -366,9 +366,7 @@ public class FlowProgrammerNorthbound {
                     + RestMessages.NOFLOW.toString());
         }
 
-        Status status = frm.toggleStaticFlowStatus(new FlowConfig("", name,
-                node, "", "", "", "", "", "", "", "", "", "", "", "", "", "",
-                "", "", "", null));
+        Status status = frm.toggleStaticFlowStatus(staticFlow);
         if (status.isSuccess()) {
             return Response.ok().build();
         }
index e6289581bded8467ff94b53478be562ae7029025..f183b516de5fb4de0b60a79618664c58108209e1 100644 (file)
@@ -154,7 +154,6 @@ public class Controller implements IController, CommandProvider {
      *
      */
     public void stop() {
-
         for (Iterator<Entry<Long, ISwitch>> it = switches.entrySet().iterator(); it
                 .hasNext();) {
             Entry<Long, ISwitch> entry = it.next();
@@ -162,7 +161,11 @@ public class Controller implements IController, CommandProvider {
             it.remove();
         }
         switchEventThread.interrupt();
-        controllerIO.shutDown();
+        try {
+               controllerIO.shutDown();
+        } catch (IOException ex) {
+               logger.error("Caught exception: " + ex + " during stop");
+        }
     }
 
     /**
@@ -227,8 +230,6 @@ public class Controller implements IController, CommandProvider {
             switchHandler.start();
             logger.info(instanceName + " connected: " + sc.toString());
         } catch (IOException e) {
-            logger
-                    .error("Caught I/O Exception when trying to accept a new connection");
             return;
         }
     }
index e1bc2d0c1446a9c6e8b2999f9345a22300b11e62..3e39ab26e6680603391da98b08bef1d82e1df6ba 100644 (file)
@@ -76,9 +76,8 @@ public class ControllerIO {
                                         serverSelectionKey);
                             }
                         }
-                    } catch (IOException e) {
-                        logger.error("Caught I/O Exception: " + e.toString());
-                        return;
+                    } catch (Exception e) {
+                        continue;
                     }
                 }
             }
@@ -87,13 +86,9 @@ public class ControllerIO {
         logger.info("Controller is now listening on port " + openFlowPort);
     }
 
-    public void shutDown() {
+    public void shutDown() throws IOException {
         this.running = false;
         this.selector.wakeup();
-        try {
-            this.serverSocket.close();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+        this.serverSocket.close();
     }
 }
index c4a85c009134c69d12de05f252ac3534da2c1801..6d94703182cf7564be00a60725cab45417046ee0 100644 (file)
@@ -9,7 +9,6 @@
 
 package org.opendaylight.controller.protocol_plugin.openflow.core.internal;
 
-import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
@@ -172,9 +171,8 @@ public class SwitchHandler implements ISwitch {
                                 handleMessages();
                             }
                         }
-                    } catch (IOException e) {
-                        logger.error("Caught I/O Exception: " + e.toString());
-                        e.printStackTrace();
+                    } catch (Exception e) {
+                       reportError(e);
                     }
                 }
             }
@@ -190,8 +188,9 @@ public class SwitchHandler implements ISwitch {
             this.clientSelectionKey.cancel();
             this.socket.close();
             executor.shutdown();
-        } catch (IOException e) {
-            logger.error("Caught IOException in stop()");
+        } catch (Exception e) {
+               // do nothing since we are shutting down.
+               return;
         }
     }
 
@@ -235,7 +234,7 @@ public class SwitchHandler implements ISwitch {
                             this.selector, SelectionKey.OP_WRITE, this);
                 }
                 logger.trace("Message sent: " + msg.toString());
-            } catch (IOException e) {
+            } catch (Exception e) {
                 reportError(e);
             }
         }
@@ -255,7 +254,7 @@ public class SwitchHandler implements ISwitch {
                     this.clientSelectionKey = this.socket.register(
                             this.selector, SelectionKey.OP_READ, this);
                 }
-            } catch (IOException e) {
+            } catch (Exception e) {
                 reportError(e);
             }
         }
@@ -358,7 +357,7 @@ public class SwitchHandler implements ISwitch {
         int bytesRead;
         try {
             bytesRead = socket.read(inBuffer);
-        } catch (IOException e) {
+        } catch (Exception e) {
             reportError(e);
             return null;
         }
index 6c394cf5c9e34bea7727f23d6628f21c0ed94330..e89beb8c3695ef417c3ef271729e73415084026b 100644 (file)
           org.slf4j,
           org.opendaylight.controller.sal.routing,
           org.opendaylight.controller.sal.core,
-          org.opendaylight.controller.sal.topology,
           org.opendaylight.controller.sal.utils,
           org.opendaylight.controller.sal.reader,
           org.apache.commons.collections15,
           org.opendaylight.controller.switchmanager, 
+          org.opendaylight.controller.topologymanager, 
           edu.uci.ics.jung.graph,
           edu.uci.ics.jung.algorithms.shortestpath,
           edu.uci.ics.jung.graph.util,
       <artifactId>switchmanager</artifactId>
       <version>0.4.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>topologymanager</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
     <dependency>
       <groupId>junit</groupId>
       <artifactId>junit</artifactId>
index 2137cda5b03ba958cb468f4b4c37b2d6a8490716..2ee1583af7ebebe7f089f2992220f69e25338ade 100644 (file)
@@ -18,9 +18,10 @@ import org.slf4j.LoggerFactory;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.opendaylight.controller.sal.routing.IListenRoutingUpdates;
 import org.opendaylight.controller.sal.routing.IRouting;
-import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.sal.reader.IReadService;
+import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
 
 public class Activator extends ComponentActivatorAbstractBase {
     protected static final Logger logger = LoggerFactory
@@ -33,7 +34,6 @@ public class Activator extends ComponentActivatorAbstractBase {
      *
      */
     public void init() {
-        logger.debug("routing.dijkstra_implementation INIT called!");
     }
 
     /**
@@ -76,8 +76,8 @@ public class Activator extends ComponentActivatorAbstractBase {
         if (imp.equals(DijkstraImplementation.class)) {
             // export the service
             Dictionary<String, String> props = new Hashtable<String, String>();
-            props.put("salListenerName", "routing.Dijkstra");
-            c.setInterface(new String[] { IListenTopoUpdates.class.getName(),
+            props.put("topoListenerName", "routing.Dijkstra");
+            c.setInterface(new String[] { ITopologyManagerAware.class.getName(),
                     IRouting.class.getName() }, props);
 
             // Now lets add a service dependency to make sure the
@@ -91,6 +91,10 @@ public class Activator extends ComponentActivatorAbstractBase {
                     ISwitchManager.class).setCallbacks("setSwitchManager",
                     "unsetSwitchManager").setRequired(true));
 
+            c.add(createContainerServiceDependency(containerName).setService(
+                    ITopologyManager.class).setCallbacks("setTopologyManager",
+                    "unsetTopologyManager").setRequired(true));
+
             c.add(createContainerServiceDependency(containerName).setService(
                     IReadService.class).setCallbacks("setReadService",
                     "unsetReadService").setRequired(true));
index 386b226567c7e938545d4b05d609a7d03bf68127..77e6d95dc953c597158be0c734355f51f2663fee 100644 (file)
@@ -25,12 +25,12 @@ import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Path;
 import org.opendaylight.controller.sal.core.Property;
 import org.opendaylight.controller.sal.core.UpdateType;
-import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
 import org.opendaylight.controller.sal.reader.IReadService;
 import org.opendaylight.controller.sal.routing.IListenRoutingUpdates;
 import org.opendaylight.controller.sal.routing.IRouting;
-import org.opendaylight.controller.sal.topology.IListenTopoUpdates;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.opendaylight.controller.topologymanager.ITopologyManager;
+import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
 
 import edu.uci.ics.jung.algorithms.shortestpath.DijkstraShortestPath;
 import edu.uci.ics.jung.graph.Graph;
@@ -39,6 +39,7 @@ import edu.uci.ics.jung.graph.util.EdgeType;
 import java.lang.Exception;
 import java.lang.IllegalArgumentException;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.Map;
@@ -48,7 +49,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.commons.collections15.Transformer;
 
-public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
+public class DijkstraImplementation implements IRouting, ITopologyManagerAware {
     private static Logger log = LoggerFactory
             .getLogger(DijkstraImplementation.class);
     private ConcurrentMap<Short, Graph<Node, Edge>> topologyBWAware;
@@ -56,6 +57,7 @@ public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
     DijkstraShortestPath<Node, Edge> mtp; //Max Throughput Path
     private Set<IListenRoutingUpdates> routingAware;
     private ISwitchManager switchManager;
+    private ITopologyManager topologyManager;
     private IReadService readService;
     private static final long DEFAULT_LINK_SPEED = Bandwidth.BW1Gbps;
 
@@ -64,7 +66,7 @@ public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
             this.routingAware = new HashSet<IListenRoutingUpdates>();
         }
         if (this.routingAware != null) {
-            log.debug("Adding routingAware listener");
+            log.debug("Adding routingAware listener: " + i);
             this.routingAware.add(i);
         }
     }
@@ -81,19 +83,6 @@ public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
         }
     }
 
-    @SuppressWarnings( { "unchecked", "rawtypes" })
-    public DijkstraImplementation() {
-        this.topologyBWAware = (ConcurrentMap<Short, Graph<Node, Edge>>) new ConcurrentHashMap();
-        this.sptBWAware = (ConcurrentMap<Short, DijkstraShortestPath<Node, Edge>>) new ConcurrentHashMap();
-        // Now create the default topology, which doesn't consider the
-        // BW, also create the corresponding Dijkstra calculation
-        Graph<Node, Edge> g = new SparseMultigraph();
-        Short sZero = Short.valueOf((short) 0);
-        this.topologyBWAware.put(sZero, g);
-        this.sptBWAware.put(sZero, new DijkstraShortestPath(g));
-        // Topologies for other BW will be added on a needed base
-    }
-
     @Override
     public synchronized void initMaxThroughput(
             final Map<Edge, Number> EdgeWeightMap) {
@@ -383,14 +372,66 @@ public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
         }
     }
 
-    public void startUp() {
-        log.debug(this.getClass().getName() + ":startUp Method Called");
+    /**
+     * Function called by the dependency manager when all the required
+     * dependencies are satisfied
+     *
+     */
+    @SuppressWarnings({ "unchecked", "rawtypes" })
+    public void init() {
+       log.debug("Routing init() is called");
+       this.topologyBWAware = (ConcurrentMap<Short, Graph<Node, Edge>>) new ConcurrentHashMap();
+       this.sptBWAware = (ConcurrentMap<Short, DijkstraShortestPath<Node, Edge>>) new ConcurrentHashMap();
+       // Now create the default topology, which doesn't consider the
+       // BW, also create the corresponding Dijkstra calculation
+       Graph<Node, Edge> g = new SparseMultigraph();
+       Short sZero = Short.valueOf((short) 0);
+       this.topologyBWAware.put(sZero, g);
+       this.sptBWAware.put(sZero, new DijkstraShortestPath(g));
+       // Topologies for other BW will be added on a needed base
     }
-
-    public void shutDown() {
-        log.debug(this.getClass().getName() + ":shutDown Method Called");
+    /**
+     * Function called by the dependency manager when at least one dependency
+     * become unsatisfied or when the component is shutting down because for
+     * example bundle is being stopped.
+     *
+     */
+    void destroy() {
+       log.debug("Routing destroy() is called");
     }
 
+    /**
+     * Function called by dependency manager after "init ()" is called
+     * and after the services provided by the class are registered in
+     * the service registry
+     *
+     */
+   void start() {
+          log.debug("Routing start() is called");
+          // build the routing database from the topology if it exists.
+          Map<Edge, Set<Property>> edges = topologyManager.getEdges();
+          if (edges.isEmpty()) {
+                  return;
+          }
+          log.debug("Creating routing database from the topology");
+          for (Iterator<Map.Entry<Edge,Set<Property>>> i = edges.entrySet().iterator();  i.hasNext();) {
+                  Map.Entry<Edge, Set<Property>> entry = i.next();
+                  Edge e = entry.getKey();
+                  Set<Property> props = entry.getValue();
+                  edgeUpdate(e, UpdateType.ADDED, props);
+          }
+   }
+
+    /**
+     * Function called by the dependency manager before the services exported by
+     * the component are unregistered, this will be followed by a "destroy ()"
+     * calls
+     *
+     */
+   public void stop() {
+          log.debug("Routing stop() is called");
+   }
+
     @Override
     public void edgeOverUtilized(Edge edge) {
         // TODO Auto-generated method stub
@@ -422,4 +463,14 @@ public class DijkstraImplementation implements IRouting, IListenTopoUpdates {
             this.readService = null;
         }
     }
+    
+    public void setTopologyManager(ITopologyManager tm) {
+       this.topologyManager = tm;
+    }
+    
+    public void unsetTopologyManager(ITopologyManager tm) {
+       if (this.topologyManager == tm) {
+               this.topologyManager = null;
+       }
+    }
 }
index 45c75f1c066d838e53f7d00633dabdf414cb3815..2022601321f58f86cf186647cb85998cc00ab8ea 100644 (file)
@@ -34,6 +34,7 @@ public class DijkstraTest {
     @Test
     public void testSinglePathRouteNoBw() {
         DijkstraImplementation imp = new DijkstraImplementation();
+        imp.init();
         Node node1 = NodeCreator.createOFNode((long) 1);
         Node node2 = NodeCreator.createOFNode((long) 2);
         Node node3 = NodeCreator.createOFNode((long) 3);
@@ -84,6 +85,7 @@ public class DijkstraTest {
     @Test
     public void testShortestPathRouteNoBw() {
         DijkstraImplementation imp = new DijkstraImplementation();
+        imp.init();
         Node node1 = NodeCreator.createOFNode((long) 1);
         Node node2 = NodeCreator.createOFNode((long) 2);
         Node node3 = NodeCreator.createOFNode((long) 3);
@@ -149,6 +151,7 @@ public class DijkstraTest {
     @Test
     public void testShortestPathRouteNoBwAfterLinkDelete() {
         DijkstraImplementation imp = new DijkstraImplementation();
+        imp.init();
         Node node1 = NodeCreator.createOFNode((long) 1);
         Node node2 = NodeCreator.createOFNode((long) 2);
         Node node3 = NodeCreator.createOFNode((long) 3);
index 1bab0789590a1192e3c49e77aa2480fdbfa4699e..77c55f3c10185ba9869b19903806b962655d1a60 100644 (file)
@@ -35,6 +35,7 @@ public class MaxThruputTest {
     @Test
     public void testMaxThruPut() {
         DijkstraImplementation imp = new DijkstraImplementation();
+        imp.init();
         Node node1 = NodeCreator.createOFNode((long) 1);
         Node node2 = NodeCreator.createOFNode((long) 2);
         Node node3 = NodeCreator.createOFNode((long) 3);
index 4cc23b4bbf6e0e492587c8847ad62b843ae7b72f..2209f84cac7ca86b29da96487dd1b45329daca5d 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.binding.impl;
 
 import java.util.HashMap;
diff --git a/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java b/opendaylight/sal/yang-prototype/sal/sal-binding-broker-impl/src/main/java/org/opendaylight/controller/sal/binding/impl/BrokerUtils.java
new file mode 100644 (file)
index 0000000..e174559
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.binding.impl;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class BrokerUtils {
+    private BrokerUtils() {
+        
+    }
+    
+    
+    public static <K,V> void addToMap(Map<Class<? extends K>, List<V>> map, Class<? extends K> key, V value) {
+        List<V> list = map.get(key);
+        if (list == null) {
+            list = new ArrayList<V>();
+            map.put(key, list);
+        }
+        list.add(value);
+    }
+
+    public static <K,V> void removeFromMap(Map<Class<? extends K>, List<V>> map, Class<? extends K> key,
+            V value) {
+        List<V> list = map.get(key);
+        if (list == null) {
+            return;
+        }
+        list.remove(value);
+        if (list.isEmpty()) {
+            map.remove(key);
+        }
+    }
+}
index 810a0cbd3031fd70b0f5c2947c33865c8051b20a..640089affb49b5b4d207e554a017dfe59d7c58ee 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.binding.impl;
 
 import org.opendaylight.controller.sal.binding.spi.MappingProvider.MappingExtension;
index 189c58555fbb562337335bac30a77c469b0b2461..f029a2f9f4bdcb3ec872338b0a56323c5511dd43 100644 (file)
@@ -1,6 +1,12 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.controller.sal.binding.impl;
 
-import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -17,7 +23,7 @@ import org.opendaylight.controller.sal.binding.spi.SALBindingModule;
 import org.opendaylight.controller.sal.binding.spi.Mapper;
 import org.opendaylight.controller.sal.binding.spi.MappingProvider;
 import org.opendaylight.controller.sal.binding.spi.MappingProvider.MappingExtensionFactory;
-import org.opendaylight.controller.sal.core.api.Provider;
+
 import org.opendaylight.controller.sal.core.api.Broker.ProviderSession;
 import org.opendaylight.controller.yang.binding.DataObject;
 import org.opendaylight.controller.yang.binding.Notification;
@@ -35,7 +41,10 @@ public class NotificationModule implements SALBindingModule {
     private MappingProvider mappingProvider;
 
     private Map<Class<? extends Notification>, List<NotificationListener>> listeners = new HashMap<Class<? extends Notification>, List<NotificationListener>>();
-    private static Logger log = LoggerFactory.getLogger(NotificationModule.class);
+    private Set<QName> biNotifications = new HashSet<QName>();
+    private static final Logger log = LoggerFactory
+            .getLogger(NotificationModule.class);
+    private final BindingIndependentListener biListener = new BindingIndependentListener();
 
     @Override
     public Set<Class<? extends BindingAwareService>> getProvidedServices() {
@@ -150,6 +159,31 @@ public class NotificationModule implements SALBindingModule {
         biNotifyService.sendNotification(domNotification);
     }
 
+    private void addBAListener(Class<? extends Notification> notificationType,
+            NotificationListener listener) {
+
+        BrokerUtils.addToMap(listeners, notificationType, listener);
+        Mapper<? extends Notification> mapper = mappingProvider
+                .getMapper(notificationType);
+        QName biType = mapper.getQName();
+        if (false == biNotifications.contains(biType)) {
+            // The listener is not registered for binding independent
+            // notification
+            biNotifications.add(biType);
+
+            if (biNotifyService != null) {
+                biNotifyService.addNotificationListener(biType, biListener);
+            }
+        }
+
+    }
+
+    private void removeBAListener(
+            Class<? extends Notification> notificationType,
+            NotificationListener listener) {
+        BrokerUtils.removeFromMap(listeners, notificationType, listener);
+    }
+
     private class NotificationSession implements NotificationService {
         private final ConsumerSession session;
 
@@ -163,16 +197,20 @@ public class NotificationModule implements SALBindingModule {
         public void addNotificationListener(
                 Class<? extends Notification> notificationType,
                 NotificationListener listener) {
-            // TODO Implement this method
-            throw new UnsupportedOperationException("Not implemented");
+
+            NotificationModule.this.addBAListener(notificationType, listener);
+            BrokerUtils.addToMap(sessionListeners, notificationType, listener);
+
         }
 
         @Override
         public void removeNotificationListener(
                 Class<? extends Notification> notificationType,
                 NotificationListener listener) {
-            // TODO Implement this method
-            throw new UnsupportedOperationException("Not implemented");
+            BrokerUtils.removeFromMap(sessionListeners, notificationType,
+                    listener);
+            NotificationModule.this
+                    .removeBAListener(notificationType, listener);
         }
 
     }
@@ -190,41 +228,47 @@ public class NotificationModule implements SALBindingModule {
         }
 
     }
-    
-    private class BindingIndependentListener implements org.opendaylight.controller.sal.core.api.notify.NotificationListener {
+
+    private class BindingIndependentListener
+            implements
+            org.opendaylight.controller.sal.core.api.notify.NotificationListener {
 
         @Override
         public Set<QName> getSupportedNotifications() {
-            return Collections.emptySet();
+            return biNotifications;
         }
 
         @Override
         public void onNotification(CompositeNode notification) {
-            NotificationModule.this.onBindingIndependentNotification(notification);
+            NotificationModule.this
+                    .onBindingIndependentNotification(notification);
         }
-        
+
     }
 
     private void onBindingIndependentNotification(CompositeNode biNotification) {
         QName biType = biNotification.getNodeType();
-        
+
         Mapper<DataObject> mapper = mappingProvider.getMapper(biType);
-        if(mapper == null) {
+        if (mapper == null) {
             log.info("Received notification does not have a binding defined.");
             return;
         }
         Class<DataObject> type = mapper.getDataObjectClass();
-        
+
         // We check if the received QName / type is really Notification
-        if(Notification.class.isAssignableFrom(type)) {
-            Notification notification = (Notification) mapper.objectFromDom(biNotification);
+        if (Notification.class.isAssignableFrom(type)) {
+            Notification notification = (Notification) mapper
+                    .objectFromDom(biNotification);
             notifyBindingAware(notification);
         } else {
-            // The generated type for this QName does not inherits from notification
-            // something went wrong - generated APIs and/or provider sending notification
+            // The generated type for this QName does not inherits from
+            // notification something went wrong - generated APIs and/or 
+            // provider sending notification
             // which was incorectly described in the YANG schema.
-            log.error("Received notification "+  biType +" is not binded as notification");
+            log.error("Received notification " + biType
+                    + " is not binded as notification");
         }
-        
+
     }
 }
index 9367645d4cb7c1b68c2777c033d2a528a8b1742e..6f7e740cdf6fd5300179b84091e3fddcb57d1c20 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.controller.sal.core.api.notify;\r
 \r
 import org.opendaylight.controller.sal.core.api.Broker;\r
-import org.opendaylight.controller.sal.core.api.BrokerService;\r
 import org.opendaylight.controller.sal.core.api.Provider;\r
 import org.opendaylight.controller.yang.data.api.CompositeNode;\r
 \r
@@ -30,7 +29,7 @@ import org.opendaylight.controller.yang.data.api.CompositeNode;
  * \r
  * \r
  */\r
-public interface NotificationProviderService extends BrokerService {\r
+public interface NotificationProviderService extends NotificationService {\r
 \r
     /**\r
      * Publishes a notification.\r
index 92d0c391d3694deade3dd564a12eee62a22ef9aa..9d24cc6fa89994a7014b15458010631e6ebb74f5 100644 (file)
@@ -94,6 +94,7 @@ public class TopologyManagerImpl implements ITopologyManager,
 
     void setTopologyManagerAware(ITopologyManagerAware s) {
         if (this.topologyManagerAware != null) {
+               log.debug("Adding ITopologyManagerAware: " + s);
             this.topologyManagerAware.add(s);
         }
     }
index 297c99c0b282e02a726f0d3a532b3e70735f116a..77470224fb5a5ba51d01c35d2e55d8e6907131d0 100644 (file)
@@ -43,9 +43,9 @@ import com.google.gson.Gson;
 @RequestMapping("/")
 public class Flows implements IOneWeb {
        private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
-    private final String WEB_NAME = "Flows";
-    private final String WEB_ID = "flows";
-    private final short WEB_ORDER = 2;
+    private static final String WEB_NAME = "Flows";
+    private static final String WEB_ID = "flows";
+    private static final short WEB_ORDER = 2;
 
     public Flows() {
         ServiceHelper.registerGlobalService(IOneWeb.class, this, null);
@@ -77,14 +77,12 @@ public class Flows implements IOneWeb {
         // fetch frm
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, "default", this);
-        if (frm == null)
-            return null;
+        if (frm == null) { return null; }
 
         // fetch sm
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null)
-            return null;
+        if (switchManager == null) { return null; }
         
         // get static flow list
         List<FlowConfig> staticFlowList = frm.getStaticFlows();
@@ -111,8 +109,7 @@ public class Flows implements IOneWeb {
     public Map<String, Object> getNodePorts() {
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null)
-            return null;
+        if (switchManager == null) { return null; }
 
         Map<String, Object> nodes = new HashMap<String, Object>();
         Map<Short, String> port;
@@ -121,7 +118,7 @@ public class Flows implements IOneWeb {
             port = new HashMap<Short, String>(); // new port
             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
 
-            if (nodeConnectorSet != null)
+            if (nodeConnectorSet != null) {
                 for (NodeConnector nodeConnector : nodeConnectorSet) {
                     String nodeConnectorName = ((Name) switchManager
                             .getNodeConnectorProp(nodeConnector,
@@ -130,6 +127,7 @@ public class Flows implements IOneWeb {
                              nodeConnectorName + "("
                              + nodeConnector.getNodeConnectorIDString() + ")");
                 }
+            }
             
             // add ports
             Map<String, Object> entry = new HashMap<String, Object>();
@@ -183,7 +181,7 @@ public class Flows implements IOneWeb {
     @ResponseBody
     public String actionFlow(@RequestParam(required = true) String action,
             @RequestParam(required = false) String body, @RequestParam(required = true) String nodeId) {
-       if (!authorize(UserLevel.NETWORKADMIN)) {
+       if (!isUserAuthorized(UserLevel.NETWORKADMIN)) {
                return "Operation not authorized";
        }
        
@@ -195,19 +193,19 @@ public class Flows implements IOneWeb {
         FlowConfig flow = gson.fromJson(body, FlowConfig.class);
         Node node = Node.fromString(nodeId);
         flow.setNode(node);
-        Status result = null;
+        Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
         if (action.equals("add")) {
             result = frm.addStaticFlow(flow, false);
         }
 
-        return result.getDescription();
+        return (result.isSuccess())? StatusCode.SUCCESS.toString(): result.getDescription();
     }
     
     @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
     @ResponseBody
     public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
                @RequestParam(required = true) String action) {
-       if (!authorize(UserLevel.NETWORKADMIN)) { return "Operation not authorized"; }
+       if (!isUserAuthorized(UserLevel.NETWORKADMIN)) { return "Operation not authorized"; }
        
        IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, "default", this);
@@ -215,39 +213,32 @@ public class Flows implements IOneWeb {
         
         Status result = null;
         Node node = Node.fromString(nodeId);
-        if (node == null) {
-            return null;
-        }
+        if (node == null) { return null; }
         if (action.equals("remove")) {
                result = frm.removeStaticFlow(name, node);
         } else if (action.equals("toggle")) {
-               FlowConfig config = frm.getStaticFlow(name, node);
-               result = frm.toggleStaticFlowStatus(config);
+               result = frm.toggleStaticFlowStatus(name, node);
         } else {
                result = new Status(StatusCode.BADREQUEST, "Unknown action");
         }
         
-        return result.getDescription();
+        return (result.isSuccess())? StatusCode.SUCCESS.toString(): result.getDescription();
     }
     
     /**
-     * Is the operation permitted for the given level
+     * Returns whether the current user's level is same or above
+     * the required authorization level. 
      * 
-     * @param level
+     * @param requiredLevel the authorization level required
      */
-    private boolean authorize(UserLevel level) {
+    private boolean isUserAuthorized(UserLevel requiredLevel) {
        IUserManager userManager = (IUserManager) ServiceHelper
                 .getGlobalInstance(IUserManager.class, this);
-        if (userManager == null) {
-               return false;
-        }
+        if (userManager == null) { return false; }
         
         String username = SecurityContextHolder.getContext().getAuthentication().getName();
         UserLevel userLevel = userManager.getUserLevel(username);
-        if (userLevel.toNumber() <= level.toNumber()) {
-               return true;
-        }
-        return false;
+        return (userLevel.ordinal() <= requiredLevel.ordinal());
     }
 
 }