Merge "Added validation of range and length constraints. Fixed base range constraints...
authorEd Warnicke <eaw@cisco.com>
Wed, 19 Jun 2013 17:40:16 +0000 (17:40 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Wed, 19 Jun 2013 17:40:16 +0000 (17:40 +0000)
22 files changed:
opendaylight/clustering/integrationtest/pom.xml
opendaylight/clustering/integrationtest/src/test/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusteringServicesIT.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/Activator.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterGlobalManager.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/ClusterManagerCommon.java
opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/GetUpdatesContainer.java [new file with mode: 0644]
opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml [deleted file]
opendaylight/clustering/services_implementation/src/test/resources/logback.xml [new file with mode: 0644]
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/authorization/Privilege.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/match/Match.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/utils/ServiceHelper.java
opendaylight/usermanager/api/src/main/java/org/opendaylight/controller/usermanager/AuthenticatedUser.java [moved from opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/AuthenticatedUser.java with 94% similarity]
opendaylight/usermanager/api/src/test/java/org/opendaylight/controller/usermanager/AuthenticatedUserTest.java [moved from opendaylight/usermanager/implementation/src/test/java/org/opendaylight/controller/usermanager/internal/AuthenticatedUserTest.java with 95% similarity]
opendaylight/usermanager/implementation/src/main/java/org/opendaylight/controller/usermanager/internal/UserManagerImpl.java
opendaylight/usermanager/implementation/src/test/java/org/opendaylight/controller/usermanager/internal/UserManagerImplTest.java
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.java
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/DevicesJsonBean.java
opendaylight/web/flows/src/main/java/org/opendaylight/controller/flows/web/Flows.java
opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java
opendaylight/web/topology/src/main/java/org/opendaylight/controller/topology/web/Topology.java
opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/Troubleshoot.java
opendaylight/web/troubleshoot/src/main/java/org/opendaylight/controller/troubleshoot/web/TroubleshootingJsonBean.java

index 52c568203be917dd42c347afbb616b9f907c5b9c..e2e27031ca43f7b150059a1910089a48c1e57020 100644 (file)
   <version>0.4.0-SNAPSHOT</version>
 
   <dependencies>
-    <dependency>
-      <groupId>org.infinispan</groupId>
-      <artifactId>infinispan-core</artifactId>
-      <version>5.2.3.Final</version>
-    </dependency>
     <dependency>
       <groupId>org.opendaylight.controller</groupId>
       <artifactId>clustering.services</artifactId>
       <artifactId>clustering.services-implementation</artifactId>
       <version>0.4.0-SNAPSHOT</version>
     </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>org.opendaylight.controller</groupId>
+      <artifactId>containermanager.implementation</artifactId>
+      <version>0.4.0-SNAPSHOT</version>
+    </dependency>
   </dependencies>
   <properties>
     <!-- Sonar jacoco plugin to get integration test coverage info -->
index 71a452b4cf57688e57b1ce7802129c9765b6594d..80f5558bcf853d91e03cf35ed95ceac3bb1419b0 100644 (file)
@@ -11,8 +11,14 @@ import static org.ops4j.pax.exam.CoreOptions.options;
 import static org.ops4j.pax.exam.CoreOptions.systemPackages;\r
 import static org.ops4j.pax.exam.CoreOptions.systemProperty;\r
 \r
+import java.util.List;\r
+import java.util.concurrent.CopyOnWriteArrayList;\r
+import java.util.concurrent.TimeUnit;\r
 import java.net.InetAddress;\r
+import java.util.Dictionary;\r
 import java.util.HashSet;\r
+import java.util.Hashtable;\r
+import java.util.Set;\r
 import java.util.List;\r
 import java.util.concurrent.ConcurrentMap;\r
 \r
@@ -24,9 +30,14 @@ import org.junit.runner.RunWith;
 import org.opendaylight.controller.clustering.services.CacheConfigException;\r
 import org.opendaylight.controller.clustering.services.CacheExistException;\r
 import org.opendaylight.controller.clustering.services.CacheListenerAddException;\r
+import org.opendaylight.controller.clustering.services.IClusterGlobalServices;\r
 import org.opendaylight.controller.clustering.services.IClusterServices;\r
+import org.opendaylight.controller.clustering.services.IClusterContainerServices;\r
 import org.opendaylight.controller.clustering.services.IClusterServices.cacheMode;\r
 import org.opendaylight.controller.clustering.services.IGetUpdates;\r
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;\r
+import org.opendaylight.controller.sal.utils.ServiceHelper;\r
+import org.opendaylight.controller.sal.core.UpdateType;\r
 import org.ops4j.pax.exam.Option;\r
 import org.ops4j.pax.exam.junit.Configuration;\r
 import org.ops4j.pax.exam.junit.PaxExam;\r
@@ -34,65 +45,73 @@ import org.ops4j.pax.exam.util.PathUtils;
 import org.osgi.framework.Bundle;\r
 import org.osgi.framework.BundleContext;\r
 import org.osgi.framework.ServiceReference;\r
+import org.osgi.framework.ServiceRegistration;\r
 import org.slf4j.Logger;\r
 import org.slf4j.LoggerFactory;\r
+import java.util.concurrent.CountDownLatch;\r
 \r
 @RunWith(PaxExam.class)\r
 public class ClusteringServicesIT {\r
     private Logger log = LoggerFactory\r
-            .getLogger(ClusteringServicesIT.class);\r
+        .getLogger(ClusteringServicesIT.class);\r
     // get the OSGI bundle context\r
     @Inject\r
     private BundleContext bc;\r
-\r
     private IClusterServices clusterServices = null;\r
+    private IClusterContainerServices clusterDefaultServices = null;\r
+    private IClusterGlobalServices clusterGlobalServices = null;\r
 \r
     // Configure the OSGi container\r
     @Configuration\r
     public Option[] config() {\r
         return options(\r
-                //\r
-                systemProperty("logback.configurationFile").value(\r
-                        "file:" + PathUtils.getBaseDir()\r
-                                + "/src/test/resources/logback.xml"),\r
-                // To start OSGi console for inspection remotely\r
-                systemProperty("osgi.console").value("2401"),\r
-                // Set the systemPackages (used by clustering)\r
-                systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),\r
-                // List framework bundles\r
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.console",\r
-                        "1.0.0.v20120522-1841"),\r
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.util",\r
-                        "1.0.400.v20120522-2049"),\r
-                mavenBundle("equinoxSDK381", "org.eclipse.osgi.services",\r
-                        "3.3.100.v20120522-1822"),\r
-                mavenBundle("equinoxSDK381", "org.eclipse.equinox.ds",\r
-                        "1.4.0.v20120522-1841"),\r
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.command",\r
-                        "0.8.0.v201108120515"),\r
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.runtime",\r
-                        "0.8.0.v201108120515"),\r
-                mavenBundle("equinoxSDK381", "org.apache.felix.gogo.shell",\r
-                        "0.8.0.v201110170705"),\r
-                // List logger bundles\r
-                mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(),\r
-                mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(),\r
-                mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(),\r
-                mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(),\r
-                // List all the bundles on which the test case depends\r
-                mavenBundle("org.opendaylight.controller",\r
+            //\r
+            systemProperty("logback.configurationFile").value(\r
+                "file:" + PathUtils.getBaseDir()\r
+                + "/src/test/resources/logback.xml"),\r
+            // To start OSGi console for inspection remotely\r
+            systemProperty("osgi.console").value("2401"),\r
+            // Set the systemPackages (used by clustering)\r
+            systemPackages("sun.reflect", "sun.reflect.misc", "sun.misc"),\r
+            // List framework bundles\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.eclipse.equinox.console").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.eclipse.equinox.util").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.eclipse.osgi.services").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.eclipse.equinox.ds").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.apache.felix.gogo.command").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.apache.felix.gogo.runtime").versionAsInProject(),\r
+            mavenBundle("equinoxSDK381",\r
+                        "org.apache.felix.gogo.shell").versionAsInProject(),\r
+            // List logger bundles\r
+            mavenBundle("org.slf4j", "slf4j-api").versionAsInProject(),\r
+            mavenBundle("org.slf4j", "log4j-over-slf4j").versionAsInProject(),\r
+            mavenBundle("ch.qos.logback", "logback-core").versionAsInProject(),\r
+            mavenBundle("ch.qos.logback", "logback-classic").versionAsInProject(),\r
+            // List all the bundles on which the test case depends\r
+            mavenBundle("org.opendaylight.controller",\r
                         "clustering.services").versionAsInProject(),\r
-                mavenBundle("org.opendaylight.controller",\r
+            mavenBundle("org.opendaylight.controller",\r
                         "clustering.services-implementation").versionAsInProject(),\r
-                mavenBundle("org.opendaylight.controller", "sal").versionAsInProject(),\r
-                mavenBundle("org.opendaylight.controller",\r
+            mavenBundle("org.opendaylight.controller", "sal").versionAsInProject(),\r
+            mavenBundle("org.opendaylight.controller",\r
                         "sal.implementation").versionAsInProject(),\r
-                mavenBundle("org.jboss.spec.javax.transaction",\r
+            mavenBundle("org.opendaylight.controller", "containermanager").versionAsInProject(),\r
+            mavenBundle("org.opendaylight.controller",\r
+                        "containermanager.implementation").versionAsInProject(),\r
+            mavenBundle("org.jboss.spec.javax.transaction",\r
                         "jboss-transaction-api_1.1_spec").versionAsInProject(),\r
-                mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),\r
-                mavenBundle("org.apache.felix",\r
+            mavenBundle("org.apache.commons", "commons-lang3").versionAsInProject(),\r
+            mavenBundle("org.apache.felix",\r
                         "org.apache.felix.dependencymanager").versionAsInProject(),\r
-                junitBundles());\r
+            mavenBundle("org.apache.felix",\r
+                        "org.apache.felix.dependencymanager.shell").versionAsInProject(),\r
+            junitBundles());\r
     }\r
 \r
     private String stateToString(int state) {\r
@@ -119,30 +138,34 @@ public class ClusteringServicesIT {
             int state = b[i].getState();\r
             if (state != Bundle.ACTIVE && state != Bundle.RESOLVED) {\r
                 log.debug("Bundle:" + b[i].getSymbolicName() + " state:"\r
-                        + stateToString(state));\r
+                          + stateToString(state));\r
                 debugit = true;\r
             }\r
         }\r
         if (debugit) {\r
             log.debug("Do some debugging because some bundle is "\r
-                    + "unresolved");\r
+                      + "unresolved");\r
         }\r
 \r
         // Assert if true, if false we are good to go!\r
         assertFalse(debugit);\r
 \r
-        ServiceReference r = bc.getServiceReference(IClusterServices.class\r
-                .getName());\r
-        if (r != null) {\r
-            this.clusterServices = (IClusterServices) bc.getService(r);\r
-        }\r
+        this.clusterServices = (IClusterServices)ServiceHelper\r
+            .getGlobalInstance(IClusterServices.class, this);\r
         assertNotNull(this.clusterServices);\r
 \r
+        this.clusterDefaultServices = (IClusterContainerServices)ServiceHelper\r
+            .getInstance(IClusterContainerServices.class, "default", this);\r
+        assertNotNull(this.clusterDefaultServices);\r
+\r
+        this.clusterGlobalServices = (IClusterGlobalServices)ServiceHelper\r
+            .getGlobalInstance(IClusterGlobalServices.class, this);\r
+        assertNotNull(this.clusterGlobalServices);\r
     }\r
 \r
     @Test\r
     public void clusterTest() throws CacheExistException, CacheConfigException,\r
-            CacheListenerAddException {\r
+        CacheListenerAddException {\r
 \r
         String container1 = "Container1";\r
         String container2 = "Container2";\r
@@ -220,7 +243,7 @@ public class ClusteringServicesIT {
         }\r
 \r
         @Override\r
-        public void entryUpdated(Integer key, String new_value,\r
+        public void entryUpdated(Integer key, String newValue,\r
                 String containerName, String cacheName, boolean originLocal) {\r
             return;\r
         }\r
@@ -231,4 +254,438 @@ public class ClusteringServicesIT {
             return;\r
         }\r
     }\r
+\r
+    @Test\r
+    public void clusterContainerAndGlobalTest() throws CacheExistException, CacheConfigException,\r
+        CacheListenerAddException, InterruptedException {\r
+        String cache1 = "Cache1";\r
+        String cache2 = "Cache2";\r
+        // Lets test the case of caches with same name in different\r
+        // containers (actually global an container case)\r
+        String cache3 = "Cache2";\r
+\r
+        HashSet<cacheMode> cacheModeSet = new HashSet<cacheMode>();\r
+        cacheModeSet.add(cacheMode.NON_TRANSACTIONAL);\r
+        ConcurrentMap cm11 = this.clusterDefaultServices.createCache(cache1, cacheModeSet);\r
+        assertNotNull(cm11);\r
+\r
+        assertTrue(this.clusterDefaultServices.existCache(cache1));\r
+        assertEquals(cm11, this.clusterDefaultServices.getCache(cache1));\r
+\r
+        ConcurrentMap cm12 = this.clusterDefaultServices.createCache(cache2, cacheModeSet);\r
+        ConcurrentMap cm23 = this.clusterGlobalServices.createCache(cache3, cacheModeSet);\r
+\r
+        // Now given cahe2 and cache3 have same name lets make sure\r
+        // they don't return the same reference\r
+        assertNotNull(this.clusterGlobalServices.getCache(cache2));\r
+        // cm12 reference must be different than cm23\r
+        assertTrue(cm12 != cm23);\r
+\r
+        HashSet<String> cacheList = (HashSet<String>) this.clusterDefaultServices\r
+            .getCacheList();\r
+        assertEquals(2, cacheList.size());\r
+        assertTrue(cacheList.contains(cache1));\r
+        assertTrue(cacheList.contains(cache2));\r
+\r
+        assertNotNull(this.clusterDefaultServices.getCacheProperties(cache1));\r
+\r
+        {\r
+            /***********************************/\r
+            /* Testing cacheAware in Container */\r
+            /***********************************/\r
+            Dictionary<String, Object> props = new Hashtable<String, Object>();\r
+            Set<String> propSet = new HashSet<String>();\r
+            propSet.add(cache1);\r
+            propSet.add(cache2);\r
+            props.put("cachenames", propSet);\r
+            CacheAware listener = new CacheAware();\r
+            CacheAware listenerRepeated = new CacheAware();\r
+            ServiceRegistration updateServiceReg = ServiceHelper.registerServiceWReg(ICacheUpdateAware.class, "default",\r
+                                                                                     listener, props);\r
+            assertNotNull(updateServiceReg);\r
+\r
+            // Register another service for the same caches, this\r
+            // should not get any update because we don't allow to\r
+            // override the existing unless before unregistered\r
+            ServiceRegistration updateServiceRegRepeated = ServiceHelper.registerServiceWReg(ICacheUpdateAware.class,\r
+                                                                                             "default",\r
+                                                                                             listenerRepeated, props);\r
+            assertNotNull(updateServiceRegRepeated);\r
+            CountDownLatch res = null;\r
+            List<Update> ups = null;\r
+            Update up = null;\r
+            Integer k1 = new Integer(10);\r
+            Long k2 = new Long(100L);\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(2);\r
+            // modify the cache\r
+            cm11.put(k1, "foo");\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 2);\r
+            // Validate that first we get an update (yes even in case of a\r
+            // new value added)\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertTrue(up.value.equals("foo"));\r
+            assertTrue(up.cacheName.equals(cache1));\r
+            // Validate that we then get a create\r
+            up = ups.get(1);\r
+            assertTrue(up.t.equals(UpdateType.ADDED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache1));\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm11.put(k1, "baz");\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get an update with expect fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertTrue(up.value.equals("baz"));\r
+            assertTrue(up.cacheName.equals(cache1));\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm11.remove(k1);\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get a delete with expected fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.REMOVED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache1));\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(2);\r
+            // modify the cache\r
+            cm12.put(k2, new Short((short)15));\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 2);\r
+            // Validate that first we get an update (yes even in case of a\r
+            // new value added)\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k2));\r
+            assertTrue(up.value.equals(new Short((short)15)));\r
+            assertTrue(up.cacheName.equals(cache2));\r
+            // Validate that we then get a create\r
+            up = ups.get(1);\r
+            assertTrue(up.t.equals(UpdateType.ADDED));\r
+            assertTrue(up.key.equals(k2));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache2));\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm12.put(k2, "BAZ");\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get an update with expect fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k2));\r
+            assertTrue(up.value.equals("BAZ"));\r
+            assertTrue(up.cacheName.equals(cache2));\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm12.remove(k2);\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get a delete with expected fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.REMOVED));\r
+            assertTrue(up.key.equals(k2));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache2));\r
+\r
+            /******************************************************************/\r
+            /* NOW LETS REMOVE THE REGISTRATION AND MAKE SURE NO UPDATS COMES */\r
+            /******************************************************************/\r
+            updateServiceReg.unregister();\r
+            // Start monitoring the updates, noone should come in\r
+            res = listener.restart(1);\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // modify the cache\r
+            cm11.put(k1, "foo");\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // modify the cache\r
+            cm11.put(k1, "baz");\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // modify the cache\r
+            cm11.remove(k1);\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // modify the cache\r
+            cm12.put(k2, new Short((short)15));\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // modify the cache\r
+            cm12.put(k2, "BAZ");\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // modify the cache\r
+            cm12.remove(k2);\r
+\r
+\r
+            // Wait to make sure no updates came in, clearly this is\r
+            // error prone as logic, but cannot find a better way than\r
+            // this to make sure updates didn't get in\r
+            res.await(1L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 0);\r
+        }\r
+\r
+        {\r
+            /***********************************/\r
+            /* Testing cacheAware in Global */\r
+            /***********************************/\r
+            Dictionary<String, Object> props = new Hashtable<String, Object>();\r
+            Set<String> propSet = new HashSet<String>();\r
+            propSet.add(cache3);\r
+            props.put("cachenames", propSet);\r
+            CacheAware listener = new CacheAware();\r
+            ServiceRegistration updateServiceReg = ServiceHelper.registerGlobalServiceWReg(ICacheUpdateAware.class,\r
+                                                                                           listener, props);\r
+            assertNotNull(updateServiceReg);\r
+\r
+            CountDownLatch res = null;\r
+            List<Update> ups = null;\r
+            Update up = null;\r
+            Integer k1 = new Integer(10);\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(2);\r
+            // modify the cache\r
+            cm23.put(k1, "foo");\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 2);\r
+            // Validate that first we get an update (yes even in case of a\r
+            // new value added)\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertTrue(up.value.equals("foo"));\r
+            assertTrue(up.cacheName.equals(cache3));\r
+            // Validate that we then get a create\r
+            up = ups.get(1);\r
+            assertTrue(up.t.equals(UpdateType.ADDED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache3));\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm23.put(k1, "baz");\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get an update with expect fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.CHANGED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertTrue(up.value.equals("baz"));\r
+            assertTrue(up.cacheName.equals(cache3));\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // Start monitoring the updates\r
+            res = listener.restart(1);\r
+            // modify the cache\r
+            cm23.remove(k1);\r
+            // Wait\r
+            res.await(100L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 1);\r
+            // Validate we get a delete with expected fields\r
+            up = ups.get(0);\r
+            assertTrue(up.t.equals(UpdateType.REMOVED));\r
+            assertTrue(up.key.equals(k1));\r
+            assertNull(up.value);\r
+            assertTrue(up.cacheName.equals(cache3));\r
+\r
+            /******************************************************************/\r
+            /* NOW LETS REMOVE THE REGISTRATION AND MAKE SURE NO UPDATS COMES */\r
+            /******************************************************************/\r
+            updateServiceReg.unregister();\r
+            // Start monitoring the updates, noone should come in\r
+            res = listener.restart(1);\r
+\r
+            /***********************/\r
+            /* CREATE NEW KEY CASE */\r
+            /***********************/\r
+            // modify the cache\r
+            cm23.put(k1, "foo");\r
+\r
+            /*******************************/\r
+            /* UPDATE AN EXISTING KEY CASE */\r
+            /*******************************/\r
+            // modify the cache\r
+            cm23.put(k1, "baz");\r
+\r
+            /********************************/\r
+            /* REMOVAL OF EXISTING KEY CASE */\r
+            /********************************/\r
+            // modify the cache\r
+            cm23.remove(k1);\r
+\r
+            // Wait to make sure no updates came in, clearly this is\r
+            // error prone as logic, but cannot find a better way than\r
+            // this to make sure updates didn't get in\r
+            res.await(1L, TimeUnit.SECONDS);\r
+            // Analyze the updates\r
+            ups = listener.getUpdates();\r
+            assertTrue(ups.size() == 0);\r
+        }\r
+\r
+        InetAddress addr = this.clusterDefaultServices.getMyAddress();\r
+        assertNotNull(addr);\r
+\r
+        List<InetAddress> addrList = this.clusterDefaultServices\r
+            .getClusteredControllers();\r
+\r
+        this.clusterDefaultServices.destroyCache(cache1);\r
+        assertFalse(this.clusterDefaultServices.existCache(cache1));\r
+    }\r
+\r
+    private class Update {\r
+        Object key;\r
+        Object value;\r
+        String cacheName;\r
+        UpdateType t;\r
+\r
+        Update (UpdateType t, Object key, Object value, String cacheName) {\r
+            this.t = t;\r
+            this.key = key;\r
+            this.value = value;\r
+            this.cacheName = cacheName;\r
+        }\r
+    }\r
+\r
+    private class CacheAware implements ICacheUpdateAware {\r
+        private CopyOnWriteArrayList<Update> gotUpdates;\r
+        private CountDownLatch latch = null;\r
+\r
+        CacheAware() {\r
+            this.gotUpdates = new CopyOnWriteArrayList<Update>();\r
+        }\r
+\r
+\r
+        /**\r
+         * Restart the monitor of the updates on the CacheAware object\r
+         *\r
+         * @param expectedOperations Number of expected updates\r
+         *\r
+         * @return a countdown latch which will be used to wait till the updates are done\r
+         */\r
+        CountDownLatch restart(int expectedOperations) {\r
+            this.gotUpdates.clear();\r
+            this.latch = new CountDownLatch(expectedOperations);\r
+            return this.latch;\r
+        }\r
+\r
+        List<Update> getUpdates() {\r
+            return this.gotUpdates;\r
+        }\r
+\r
+        @Override\r
+        public void entryCreated(Object key, String cacheName, boolean originLocal) {\r
+            log.debug("CACHE[{}] Got an entry created for key:{}", cacheName, key);\r
+            Update u = new Update(UpdateType.ADDED, key, null, cacheName);\r
+            this.gotUpdates.add(u);\r
+            this.latch.countDown();\r
+        }\r
+\r
+        @Override\r
+        public void entryUpdated(Object key, Object newValue, String cacheName, boolean originLocal) {\r
+            log.debug("CACHE[{}] Got an entry updated for key:{} newValue:{}", cacheName, key, newValue);\r
+            Update u = new Update(UpdateType.CHANGED, key, newValue, cacheName);\r
+            this.gotUpdates.add(u);\r
+            this.latch.countDown();\r
+        }\r
+\r
+        @Override\r
+        public void entryDeleted(Object key, String cacheName, boolean originLocal) {\r
+            log.debug("CACHE[{}] Got an entry delete for key:{}", cacheName, key);\r
+            Update u = new Update(UpdateType.REMOVED, key, null, cacheName);\r
+            this.gotUpdates.add(u);\r
+            this.latch.countDown();\r
+        }\r
+    }\r
 }\r
index 79af2cf3989f46a9d1296692f44eff4cdfb59d66..cb96ad5c8ece76fab65b518f9ddea8eb4b67c374 100644 (file)
@@ -84,26 +84,27 @@ public class Activator extends ComponentActivatorAbstractBase {
      */
     public void configureInstance(Component c, Object imp, String containerName) {
         if (imp.equals(ClusterContainerManager.class)) {
-            c.setInterface(new String[] { IClusterContainerServices.class
-                    .getName() }, null);
+            c.setInterface(new String[] { IClusterContainerServices.class.getName() },
+                           null);
 
-            c.add(createServiceDependency().setService(IClusterServices.class)
-                    .setCallbacks("setClusterService", "unsetClusterService")
-                    .setRequired(true));
+            c.add(createServiceDependency()
+                  .setService(IClusterServices.class)
+                  .setCallbacks("setClusterService", "unsetClusterService")
+                  .setRequired(true));
 
             // CacheUpdate services will be none or many so the
             // dependency is optional
-            c.add(createContainerServiceDependency(containerName).setService(
-                    ICacheUpdateAware.class).setCallbacks(
-                    "setCacheUpdateAware", "unsetCacheUpdateAware")
-                    .setRequired(false));
+            c.add(createContainerServiceDependency(containerName)
+                  .setService(ICacheUpdateAware.class)
+                  .setCallbacks("setCacheUpdateAware", "unsetCacheUpdateAware")
+                  .setRequired(false));
 
             // Coordinator change event can be one or many so
             // dependency is optional
-            c.add(createContainerServiceDependency(containerName).setService(
-                    ICoordinatorChangeAware.class).setCallbacks(
-                    "setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
-                    .setRequired(false));
+            c.add(createContainerServiceDependency(containerName)
+                  .setService(ICoordinatorChangeAware.class)
+                  .setCallbacks("setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
+                  .setRequired(false));
         }
     }
 
@@ -120,30 +121,30 @@ public class Activator extends ComponentActivatorAbstractBase {
     public void configureGlobalInstance(Component c, Object imp) {
         if (imp.equals(ClusterManager.class)) {
             // export the service for Apps and Plugins
-            c.setInterface(new String[] { IClusterServices.class.getName() },
-                    null);
+            c.setInterface(new String[] { IClusterServices.class.getName() }, null);
         }
 
         if (imp.equals(ClusterGlobalManager.class)) {
-            c.setInterface(new String[] { IClusterGlobalServices.class
-                    .getName() }, null);
+            c.setInterface(new String[] { IClusterGlobalServices.class.getName() }, null);
 
-            c.add(createServiceDependency().setService(IClusterServices.class)
-                    .setCallbacks("setClusterService", "unsetClusterService")
-                    .setRequired(true));
+            c.add(createServiceDependency()
+                  .setService(IClusterServices.class)
+                  .setCallbacks("setClusterService", "unsetClusterService")
+                  .setRequired(true));
 
             // CacheUpdate services will be none or many so the
             // dependency is optional
-            c.add(createServiceDependency().setService(ICacheUpdateAware.class)
-                    .setCallbacks("setCacheUpdateAware",
-                            "unsetCacheUpdateAware").setRequired(false));
+            c.add(createServiceDependency()
+                  .setService(ICacheUpdateAware.class)
+                  .setCallbacks("setCacheUpdateAware", "unsetCacheUpdateAware")
+                  .setRequired(false));
 
             // Coordinator change event can be one or many so
             // dependency is optional
-            c.add(createServiceDependency().setService(
-                    ICoordinatorChangeAware.class).setCallbacks(
-                    "setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
-                    .setRequired(false));
+            c.add(createServiceDependency()
+                  .setService(ICoordinatorChangeAware.class)
+                  .setCallbacks("setCoordinatorChangeAware", "unsetCoordinatorChangeAware")
+                  .setRequired(false));
         }
     }
 }
index 8211846dd65dccc23126b58f22b930c21ce6d0c4..ce33ac8639cf89977c1c1f7f79d19e15a2da3dae 100644 (file)
@@ -9,8 +9,36 @@
 
 package org.opendaylight.controller.clustering.services_implementation.internal;
 
+import java.util.Map;
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
 import org.opendaylight.controller.clustering.services.IClusterGlobalServices;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
-public class ClusterGlobalManager extends ClusterManagerCommon implements
-        IClusterGlobalServices {
+public class ClusterGlobalManager
+    extends ClusterManagerCommon
+    implements IClusterGlobalServices {
+    protected static final Logger logger = LoggerFactory.getLogger(ClusterGlobalManager.class);
+
+    @Override
+    void setCacheUpdateAware(Map props, ICacheUpdateAware s) {
+        logger.trace("setCacheUpdateAware");
+        if (props.get("containerName") != null) {
+            // If we got a reference with the containerName property
+            // that is not what we are looking for, so filter it out.
+            return;
+        }
+        super.setCacheUpdateAware(props, s);
+    }
+
+    @Override
+    void unsetCacheUpdateAware(Map props, ICacheUpdateAware s) {
+        logger.trace("unsetCacheUpdateAware");
+        if (props.get("containerName") != null) {
+            // If we got a reference with the containerName property
+            // that is not what we are looking for, so filter it out.
+            return;
+        }
+        super.unsetCacheUpdateAware(props, s);
+    }
 }
index 7bf495426f61cfb4d177583b157beafa873d6edf..fabf3e9f1d704413346d97b98c561e8d2adc8a16 100644 (file)
 package org.opendaylight.controller.clustering.services_implementation.internal;
 
 import java.net.InetAddress;
+import java.util.Collections;
+import java.util.Dictionary;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
-
 import javax.transaction.HeuristicMixedException;
 import javax.transaction.HeuristicRollbackException;
 import javax.transaction.NotSupportedException;
@@ -22,7 +26,7 @@ import javax.transaction.RollbackException;
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import javax.transaction.TransactionManager;
-
+import org.apache.felix.dm.Component;
 import org.opendaylight.controller.clustering.services.CacheConfigException;
 import org.opendaylight.controller.clustering.services.CacheExistException;
 import org.opendaylight.controller.clustering.services.CacheListenerAddException;
@@ -35,20 +39,13 @@ import org.opendaylight.controller.clustering.services.ListenRoleChangeAddExcept
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.util.Dictionary;
-import java.util.Collections;
-import java.util.HashSet;
-import org.apache.felix.dm.Component;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
 abstract public class ClusterManagerCommon implements IClusterServicesCommon {
     protected String containerName = null;
     private IClusterServices clusterService = null;
     protected static final Logger logger = LoggerFactory
             .getLogger(ClusterManagerCommon.class);
-    private Set<ICacheUpdateAware> cacheUpdateAware = Collections
-            .synchronizedSet(new HashSet<ICacheUpdateAware>());
+    private ConcurrentMap<String, GetUpdatesContainer> cacheUpdateAware =
+        new ConcurrentHashMap<String, GetUpdatesContainer>();
     private Set<ICoordinatorChangeAware> coordinatorChangeAware = Collections
             .synchronizedSet(new HashSet<ICoordinatorChangeAware>());
     private ListenCoordinatorChange coordinatorChangeListener = null;
@@ -85,15 +82,60 @@ abstract public class ClusterManagerCommon implements IClusterServicesCommon {
         }
     }
 
-    void setCacheUpdateAware(ICacheUpdateAware s) {
+    void setCacheUpdateAware(Map props, ICacheUpdateAware s) {
+        logger.trace("CacheUpdateAware being set on container:{}",
+                     this.containerName);
         if (this.cacheUpdateAware != null) {
-            this.cacheUpdateAware.add(s);
+            Set<String> caches = (Set<String>)props.get("cachenames");
+            if (caches != null) {
+                logger.trace("cachenames provided below:");
+                for (String cache : caches) {
+                    if (this.cacheUpdateAware.get(cache) != null) {
+                        logger.error("cachename:{} on container:{} has " +
+                                     "already a listener", cache,
+                                     this.containerName);
+                    } else {
+                        GetUpdatesContainer<?, ?> up =
+                            new GetUpdatesContainer(s, this.containerName,
+                                                    cache);
+                        if (up != null) {
+                            try {
+                                this.clusterService.addListener(this.containerName,
+                                                                cache, up);
+                                this.cacheUpdateAware.put(cache, up);
+                                logger.trace("cachename:{} on container:{} has " +
+                                             "been registered", cache,
+                                             this.containerName);
+                            } catch (CacheListenerAddException exc) {
+                                // Do nothing, the important is that
+                                // we don't register the listener in
+                                // the shadow, and we are not doing
+                                // that.
+                            }
+                        }
+                    }
+                }
+            }
         }
     }
 
-    void unsetCacheUpdateAware(ICacheUpdateAware s) {
+    void unsetCacheUpdateAware(Map props, ICacheUpdateAware s) {
+        logger.trace("CacheUpdateAware being unset on container:{}",
+                     this.containerName);
         if (this.cacheUpdateAware != null) {
-            this.cacheUpdateAware.remove(s);
+            Set<String> caches = (Set<String>)props.get("cachenames");
+            if (caches != null) {
+                logger.trace("cachenames provided below:");
+                GetUpdatesContainer<?, ?> up = null;
+                for (String cache : caches) {
+                    up = this.cacheUpdateAware.get(cache);
+                    if (up != null) {
+                        this.cacheUpdateAware.remove(cache);
+                        this.clusterService.removeListener(this.containerName,
+                                                           cache, up);
+                    }
+                }
+            }
         }
     }
 
diff --git a/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/GetUpdatesContainer.java b/opendaylight/clustering/services_implementation/src/main/java/org/opendaylight/controller/clustering/services_implementation/internal/GetUpdatesContainer.java
new file mode 100644 (file)
index 0000000..3444a17
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * 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.clustering.services_implementation.internal;
+
+import org.opendaylight.controller.clustering.services.IGetUpdates;
+import org.opendaylight.controller.clustering.services.ICacheUpdateAware;
+
+public class GetUpdatesContainer<K,V> implements IGetUpdates<K,V> {
+    private ICacheUpdateAware<K,V> toBeUpdated;
+    private String containerName;
+    private String cacheName;
+
+    public GetUpdatesContainer(ICacheUpdateAware<K,V> i, String containerName,
+                               String cacheName) {
+        this.toBeUpdated = i;
+        this.containerName = containerName;
+        this.cacheName = cacheName;
+    }
+
+    public ICacheUpdateAware<K,V> whichListener() {
+        return this.toBeUpdated;
+    }
+
+    @Override
+    public void entryCreated(K key, String containerName, String cacheName,
+                             boolean local) {
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryCreated(key, cacheName, local);
+        }
+    }
+
+    @Override
+    public void entryUpdated(K key, V new_value, String containerName,
+                             String cacheName,
+                             boolean local) {
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryUpdated(key, new_value, cacheName, local);
+        }
+    }
+
+    @Override
+    public void entryDeleted(K key, String containerName, String cacheName,
+                             boolean local) {
+        if (this.toBeUpdated != null) {
+            this.toBeUpdated.entryDeleted(key, cacheName, local);
+        }
+    }
+}
diff --git a/opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml b/opendaylight/clustering/services_implementation/src/main/resources/OSGI-INF/component-cachemanager.xml
deleted file mode 100644 (file)
index f3baf79..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0"
-               activate="start"
-               deactivate="stop"
-               immediate="true"
-               name="org.opendaylight.controller.clustering.services_implementation.internal.ClusterManager">
-  <implementation class="org.opendaylight.controller.clustering.services_implementation.internal.ClusterManager"/>
-  <service>
-    <provide interface="org.opendaylight.controller.clustering.services.IClusterServices"/>
-  </service>
-</scr:component>
diff --git a/opendaylight/clustering/services_implementation/src/test/resources/logback.xml b/opendaylight/clustering/services_implementation/src/test/resources/logback.xml
new file mode 100644 (file)
index 0000000..6d9dfda
--- /dev/null
@@ -0,0 +1,12 @@
+<configuration scan="true">
+  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+    <encoder>
+      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+      </pattern>
+    </encoder>
+  </appender>
+
+  <root level="error">
+    <appender-ref ref="STDOUT" />
+  </root>
+</configuration>
index 63babe7d0a0399ba3e5b9752b5a87740d3f712b7..fb9662366f455f98429e7647044d79caa2bc6417 100644 (file)
@@ -9,10 +9,12 @@
 
 package org.opendaylight.controller.sal.authorization;
 
+import java.io.Serializable;
+
 /**
  * It represents the group/resource access privilege
  */
-public enum Privilege {
+public enum Privilege implements Serializable {
     NONE(""), // no privilege
     READ("r"), // read only
     USE("u"), // use
index 00a2f57308d57e1d76c8f0e88aeb86d74a3f910a..4dcf2b3c3764790e3aab70da16512573b8c3975a 100644 (file)
@@ -225,13 +225,14 @@ public class Match implements Cloneable, Serializable {
         Match reverse = this.clone();
 
         // Flip symmetric fields
-        for (Map.Entry<MatchType, MatchType> entry : Match.reversableMatches
-                .entrySet()) {
+        for (Map.Entry<MatchType, MatchType> entry : Match.reversableMatches.entrySet()) {
             MatchType from = entry.getKey();
             MatchType to = entry.getValue();
             if (this.isPresent(from)) {
-                reverse.setField(to, this.getField(from).getValue(), this
-                        .getField(from).getMask());
+                reverse.setField(to, this.getField(from).getValue(), this.getField(from).getMask());
+                if (!this.isPresent(to)) {
+                    reverse.clearField(from);
+                }
             }
         }
 
index ef9f2f4bada62350d979e4ee0842e45018a9885e..0237b9c499a599ffb646e7252aa723a8e18cd462 100644 (file)
@@ -65,27 +65,65 @@ public class ServiceHelper {
      * @return true if registration happened, false otherwise
      */
     public static boolean registerGlobalService(Class<?> clazz,
-            Object instance, Dictionary<String, Object> properties) {
+                                                Object instance,
+                                                Dictionary<String, Object> properties) {
+        ServiceRegistration registration = registerGlobalServiceWReg(clazz, instance, properties);
+        if (registration == null) {
+            logger.error("Failed to register {} for instance {}", clazz, instance);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Register a Service in the OSGi service registry and return the ServiceRegistration
+     *
+     * @param clazz The target class
+     * @param containerName The container name
+     * @param instance of the object exporting the service, be careful
+     * the object must implement/extend clazz else the registration
+     * will fail unless a ServiceFactory is passed as parameter
+     * @param properties The properties to be attached to the service
+     * registration
+     * @return the ServiceRegistration if registration happened, null otherwise
+     */
+    public static ServiceRegistration registerServiceWReg(Class<?> clazz, String containerName,
+                                                          Object instance, Dictionary<String, Object> properties) {
+        if (properties == null) {
+            properties = (Dictionary<String, Object>) new Hashtable<String, Object>();
+        }
+        properties.put("containerName", containerName);
+        return registerGlobalServiceWReg(clazz, instance, properties);
+    }
+
+    /**
+     * Register a Global Service in the OSGi service registry
+     *
+     * @param clazz The target class
+     * @param instance of the object exporting the service, be careful
+     * the object must implement/extend clazz else the registration
+     * will fail unless a ServiceFactory is passed as parameter
+     * @param properties The properties to be attached to the service
+     * registration
+     * @return the ServiceRegistration if registration happened, null otherwise
+     */
+    public static ServiceRegistration registerGlobalServiceWReg(Class<?> clazz,
+                                                                Object instance,
+                                                                Dictionary<String, Object> properties) {
         try {
-            BundleContext bCtx = FrameworkUtil.getBundle(instance.getClass())
-                    .getBundleContext();
+            BundleContext bCtx = FrameworkUtil.getBundle(instance.getClass()).getBundleContext();
             if (bCtx == null) {
                 logger.error("Could not retrieve the BundleContext");
-                return false;
+                return null;
             }
 
-            ServiceRegistration registration = bCtx.registerService(clazz
-                    .getName(), instance, properties);
-            if (registration == null) {
-                logger.error("Failed to register {} for instance {}", clazz,
-                        instance);
-            }
-            return true;
+            ServiceRegistration registration = bCtx.registerService(clazz.getName(), instance, properties);
+            return registration;
         } catch (Exception e) {
             logger.error("Exception {} while registering the service {}",
-                    e.getMessage(), instance.toString());
+                         e.getMessage(), instance.toString());
         }
-        return false;
+        return null;
     }
 
     /**
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.controller.usermanager.internal;
+package org.opendaylight.controller.usermanager;
 
 import java.io.Serializable;
 import java.util.ArrayList;
@@ -14,7 +14,6 @@ import java.util.Date;
 import java.util.List;
 
 import org.opendaylight.controller.sal.authorization.UserLevel;
-import org.opendaylight.controller.usermanager.ODLUserLevel;
 import org.springframework.security.core.GrantedAuthority;
 import org.springframework.security.core.authority.SimpleGrantedAuthority;
 
@@ -6,7 +6,7 @@
  * and is available at http://www.eclipse.org/legal/epl-v10.html
  */
 
-package org.opendaylight.controller.usermanager.internal;
+package org.opendaylight.controller.usermanager;
 
 import java.util.Arrays;
 import java.util.List;
@@ -16,6 +16,7 @@ import org.junit.BeforeClass;
 import org.junit.Test;
 
 import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.usermanager.AuthenticatedUser;
 import org.springframework.security.core.GrantedAuthority;
 
 public class AuthenticatedUserTest {
index faa6e3b96fe4ac5b0df16c1dc274cd812edf443a..9d2ad05765dcc5085247c1aa23025a45aad3d3b5 100644 (file)
@@ -43,6 +43,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.usermanager.AuthResponse;
+import org.opendaylight.controller.usermanager.AuthenticatedUser;
 import org.opendaylight.controller.usermanager.AuthorizationConfig;
 import org.opendaylight.controller.usermanager.IAAAProvider;
 import org.opendaylight.controller.usermanager.ISessionManager;
@@ -51,7 +52,6 @@ import org.opendaylight.controller.usermanager.ServerConfig;
 import org.opendaylight.controller.usermanager.UserConfig;
 import org.opendaylight.controller.usermanager.security.SessionManager;
 import org.opendaylight.controller.usermanager.security.UserSecurityContextRepository;
-import org.opendaylight.controller.usermanager.internal.AuthenticatedUser;
 
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.FrameworkUtil;
index e8748d8200d23430324fa2ded147ed95aacab9a8..e84396b0f49cc8cc9bab1126ec633d77a0ec2036 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.controller.sal.authorization.AuthResultEnum;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.usermanager.AuthResponse;
+import org.opendaylight.controller.usermanager.AuthenticatedUser;
 import org.opendaylight.controller.usermanager.IAAAProvider;
 import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.usermanager.ServerConfig;
index 188be8aee6f1ee4865b159d1f2225ec6f1534021..534c2c293c9c9fecc9bf8467fc74d0e237261ac9 100644 (file)
@@ -20,7 +20,6 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.codehaus.jackson.map.ObjectMapper;
-import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.web.DaylightWebUtil;
 import org.opendaylight.controller.web.IDaylightWeb;
 import org.springframework.stereotype.Controller;
@@ -30,12 +29,14 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.core.Config;
 import org.opendaylight.controller.sal.core.Name;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Tier;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.HexEncode;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
@@ -82,13 +83,20 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodesLearnt", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getNodesLearnt(HttpServletRequest request, @RequestParam(required = false) String container) {
+    public DevicesJsonBean getNodesLearnt(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
         Gson gson = new Gson();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
-        if (switchManager != null) {
+        if (switchManager != null && privilege != Privilege.NONE) {
             for (Switch device : switchManager.getNetworkDevices()) {
                 HashMap<String, String> nodeDatum = new HashMap<String, String>();
                 Node node = device.getNode();
@@ -174,6 +182,7 @@ public class Devices implements IDaylightWeb {
 
         DevicesJsonBean result = new DevicesJsonBean();
         result.setNodeData(nodeData);
+        result.setPrivilege(privilege);
         List<String> columnNames = new ArrayList<String>();
         columnNames.add("Node ID");
         columnNames.add("Node Name");
@@ -199,13 +208,19 @@ public class Devices implements IDaylightWeb {
             @RequestParam("nodeId") String nodeId,
             @RequestParam("tier") String tier,
             @RequestParam("operationMode") String operationMode,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -224,9 +239,16 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getStaticRoutes(HttpServletRequest request, @RequestParam(required = false) String container) {
+    public DevicesJsonBean getStaticRoutes(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
         Gson gson = new Gson();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                 .getInstance(IForwardingStaticRouting.class, containerName,
                         this);
@@ -239,16 +261,19 @@ public class Devices implements IDaylightWeb {
         if (routeConfigs == null) {
             return null;
         }
-        for (StaticRouteConfig conf : routeConfigs.values()) {
-            Map<String, String> staticRoute = new HashMap<String, String>();
-            staticRoute.put("name", conf.getName());
-            staticRoute.put("staticRoute", conf.getStaticRoute());
-            staticRoute.put("nextHopType", conf.getNextHopType());
-            staticRoute.put("nextHop", conf.getNextHop());
-            staticRoute.put("json", gson.toJson(conf));
-            staticRoutes.add(staticRoute);
+        if (privilege != Privilege.NONE) {
+            for (StaticRouteConfig conf : routeConfigs.values()) {
+                Map<String, String> staticRoute = new HashMap<String, String>();
+                staticRoute.put("name", conf.getName());
+                staticRoute.put("staticRoute", conf.getStaticRoute());
+                staticRoute.put("nextHopType", conf.getNextHopType());
+                staticRoute.put("nextHop", conf.getNextHop());
+                staticRoute.put("json", gson.toJson(conf));
+                staticRoutes.add(staticRoute);
+            }
         }
         DevicesJsonBean result = new DevicesJsonBean();
+        result.setPrivilege(privilege);
         result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
         result.setNodeData(staticRoutes);
         return result;
@@ -260,13 +285,19 @@ public class Devices implements IDaylightWeb {
             @RequestParam("routeName") String routeName,
             @RequestParam("staticRoute") String staticRoute,
             @RequestParam("nextHop") String nextHop,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil
+                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean result = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                     .getInstance(IForwardingStaticRouting.class, containerName,
@@ -294,13 +325,18 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteStaticRoute(
             @RequestParam("routesToDelete") String routesToDelete,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                     .getInstance(IForwardingStaticRouting.class, containerName,
@@ -329,22 +365,33 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnets", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getSubnetGateways(HttpServletRequest request, @RequestParam(required = false) String container) {
+    public DevicesJsonBean getSubnetGateways(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
         Gson gson = new Gson();
         List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
-        if (switchManager != null) {
-            for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
-                Map<String, String> subnet = new HashMap<String, String>();
-                subnet.put("name", conf.getName());
-                subnet.put("subnet", conf.getSubnet());
-                subnet.put("json", gson.toJson(conf));
-                subnets.add(subnet);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(
+                userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
+                    .getInstance(ISwitchManager.class, containerName, this);
+            if (switchManager != null) {
+                for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
+                    Map<String, String> subnet = new HashMap<String, String>();
+                    subnet.put("name", conf.getName());
+                    subnet.put("subnet", conf.getSubnet());
+                    subnet.put("json", gson.toJson(conf));
+                    subnets.add(subnet);
+                }
             }
         }
         DevicesJsonBean result = new DevicesJsonBean();
+        result.setPrivilege(privilege);
         result.setColumnNames(SubnetConfig.getGuiFieldsNames());
         result.setNodeData(subnets);
         return result;
@@ -355,13 +402,18 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean addSubnetGateways(
             @RequestParam("gatewayName") String gatewayName,
             @RequestParam("gatewayIPAddress") String gatewayIPAddress,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -386,13 +438,18 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteSubnetGateways(
             @RequestParam("gatewaysToDelete") String gatewaysToDelete,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, container, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -419,14 +476,18 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean addSubnetGatewayPort(
             @RequestParam("portsName") String portsName,
             @RequestParam("ports") String ports,
-            @RequestParam("nodeId") String nodeId,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            @RequestParam("nodeId") String nodeId, HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -453,13 +514,18 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean deleteSubnetGatewayPort(
             @RequestParam("gatewayName") String gatewayName,
             @RequestParam("nodePort") String nodePort,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -483,38 +549,51 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getSpanPorts(HttpServletRequest request, @RequestParam(required = false) String container) {
+    public DevicesJsonBean getSpanPorts(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
         Gson gson = new Gson();
-        List<String> spanConfigs_json = new ArrayList<String>();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
-        if (switchManager != null) {
-            for (SpanConfig conf : switchManager.getSpanConfigList()) {
-                spanConfigs_json.add(gson.toJson(conf));
-            }
-        }
-        ObjectMapper mapper = new ObjectMapper();
         List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
-        for (String config_json : spanConfigs_json) {
-            try {
-                @SuppressWarnings("unchecked")
-                Map<String, String> config_data = mapper.readValue(config_json,
-                        HashMap.class);
-                Map<String, String> config = new HashMap<String, String>();
-                for (String name : config_data.keySet()) {
-                    config.put(name, config_data.get(name));
-                    // Add switch name value (non-configuration field)
-                    config.put("nodeName",
-                            getNodeDesc(config_data.get("nodeId"), containerName));
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(
+                userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            List<String> spanConfigs_json = new ArrayList<String>();
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
+                    .getInstance(ISwitchManager.class, containerName, this);
+            if (switchManager != null) {
+                for (SpanConfig conf : switchManager.getSpanConfigList()) {
+                    spanConfigs_json.add(gson.toJson(conf));
+                }
+            }
+            ObjectMapper mapper = new ObjectMapper();
+
+            for (String config_json : spanConfigs_json) {
+                try {
+                    @SuppressWarnings("unchecked")
+                    Map<String, String> config_data = mapper.readValue(config_json,
+                            HashMap.class);
+                    Map<String, String> config = new HashMap<String, String>();
+                    for (String name : config_data.keySet()) {
+                        config.put(name, config_data.get(name));
+                        // Add switch name value (non-configuration field)
+                        config.put("nodeName",
+                                getNodeDesc(config_data.get("nodeId"), containerName));
+                    }
+                    config.put("json", config_json);
+                    spanConfigs.add(config);
+                } catch (Exception e) {
+                    // TODO: Handle the exception.
                 }
-                config.put("json", config_json);
-                spanConfigs.add(config);
-            } catch (Exception e) {
-                // TODO: Handle the exception.
             }
         }
+
         DevicesJsonBean result = new DevicesJsonBean();
+        result.setPrivilege(privilege);
         result.setColumnNames(SpanConfig.getGuiFieldsNames());
         result.setNodeData(spanConfigs);
         return result;
@@ -522,8 +601,18 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodeports")
     @ResponseBody
-    public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+    public Map<String, Object> getNodePorts(HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
+
+
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
@@ -537,7 +626,7 @@ public class Devices implements IDaylightWeb {
             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,
@@ -545,6 +634,7 @@ public class Devices implements IDaylightWeb {
                     port.put((Short) nodeConnector.getID(), nodeConnectorName
                             + "(" + nodeConnector.getID() + ")");
                 }
+            }
 
             nodes.put(node.getNode().toString(), port);
         }
@@ -556,15 +646,20 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean addSpanPort(
             @RequestParam("jsonData") String jsonData,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
             Gson gson = new Gson();
-            String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
             SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
@@ -588,15 +683,20 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteSpanPorts(
             @RequestParam("spanPortsToDelete") String spanPortsToDelete,
-            HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
+            HttpServletRequest request,
+            @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT
+                .toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
             Gson gson = new Gson();
-            String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
             String[] spans = spanPortsToDelete.split("###");
@@ -634,26 +734,6 @@ public class Devices implements IDaylightWeb {
                 : description;
     }
 
-    /**
-     * Is the operation permitted for the given level
-     *
-     * @param level
-     */
-    private boolean authorize(UserLevel level, HttpServletRequest request) {
-        IUserManager userManager = (IUserManager) ServiceHelper
-                .getGlobalInstance(IUserManager.class, this);
-        if (userManager == null) {
-            return false;
-        }
-
-        String username = request.getUserPrincipal().getName();
-        UserLevel userLevel = userManager.getUserLevel(username);
-        if (userLevel.toNumber() <= level.toNumber()) {
-            return true;
-        }
-        return false;
-    }
-
     private StatusJsonBean unauthorizedMessage() {
         StatusJsonBean message = new StatusJsonBean();
         message.setStatus(false);
index 6b77f119edcea1bf6e656ffe46eef6e9b16d39aa..ce0b3763e06bb26f1e3c46e657e8fa4f2e2c5447 100644 (file)
@@ -11,9 +11,12 @@ package org.opendaylight.controller.devices.web;
 import java.util.List;
 import java.util.Map;
 
+import org.opendaylight.controller.sal.authorization.Privilege;
+
 public class DevicesJsonBean {
     private List<String> columnNames;
     private List<Map<String, String>> nodeData;
+    private Privilege privilege;
 
     public List<String> getColumnNames() {
         return columnNames;
@@ -30,4 +33,12 @@ public class DevicesJsonBean {
     public void setNodeData(List<Map<String, String>> nodeData) {
         this.nodeData = nodeData;
     }
+
+    public void setPrivilege(Privilege privilege) {
+        this.privilege = privilege;
+    }
+
+    public Privilege getPrivilege() {
+        return privilege;
+    }
 }
index e1cfcc57087d4c1ca340f0fc13dccfd7d2ab5fb1..f9e6a6aaae24aef573a32a7acda652a731b3d64a 100644 (file)
@@ -18,17 +18,18 @@ import javax.servlet.http.HttpServletRequest;
 
 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.core.Name;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Switch;
 import org.opendaylight.controller.switchmanager.SwitchConfig;
-import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.web.DaylightWebUtil;
 import org.opendaylight.controller.web.IDaylightWeb;
 import org.springframework.stereotype.Controller;
@@ -75,7 +76,13 @@ public class Flows implements IDaylightWeb {
     @RequestMapping(value = "/main")
     @ResponseBody
     public Set<Map<String, Object>> getFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
 
         // fetch frm
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
@@ -112,7 +119,13 @@ public class Flows implements IDaylightWeb {
     @RequestMapping(value = "/node-ports")
     @ResponseBody
     public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
@@ -159,7 +172,13 @@ public class Flows implements IDaylightWeb {
     @RequestMapping(value = "/node-flows")
     @ResponseBody
     public Map<String, Object> getNodeFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
+            return null;
+        }
 
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
@@ -198,12 +217,14 @@ public class Flows implements IDaylightWeb {
             @RequestParam(required = false) String body,
             @RequestParam(required = true) String nodeId,
             HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!isUserAuthorized(UserLevel.NETWORKADMIN, request)) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return "Operation not authorized";
         }
 
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, containerName, this);
         if (frm == null) {
@@ -229,12 +250,14 @@ public class Flows implements IDaylightWeb {
             @PathVariable("name") String name,
             @RequestParam(required = true) String action,
             HttpServletRequest request, @RequestParam(required = false) String container) {
-        if (!isUserAuthorized(UserLevel.NETWORKADMIN, request)) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Authorization check
+        String userName = request.getUserPrincipal().getName();
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return "Operation not authorized";
         }
 
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, containerName, this);
         if (frm == null) {
@@ -257,25 +280,4 @@ public class Flows implements IDaylightWeb {
         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
                 .getDescription();
     }
-
-    /**
-     * Returns whether the current user's level is same or above the required
-     * authorization level.
-     *
-     * @param requiredLevel
-     *            the authorization level required
-     */
-    private boolean isUserAuthorized(UserLevel requiredLevel,
-            HttpServletRequest request) {
-        IUserManager userManager = (IUserManager) ServiceHelper
-                .getGlobalInstance(IUserManager.class, this);
-        if (userManager == null) {
-            return false;
-        }
-
-        String username = request.getUserPrincipal().getName();
-        UserLevel userLevel = userManager.getUserLevel(username);
-        return (userLevel.ordinal() <= requiredLevel.ordinal());
-    }
-
 }
index a7f7133cb2a8b634d871f1ef53a550d2b0a1a15d..ab2abe9c9ed136e32d15d5c3f992dde5cd4d9b8e 100644 (file)
@@ -1,43 +1,55 @@
 package org.opendaylight.controller.web;
 
-import java.util.Set;
-
-import javax.servlet.http.HttpServletRequest;
-
 import org.opendaylight.controller.containermanager.IContainerAuthorization;
-import org.opendaylight.controller.sal.authorization.Resource;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
+import org.opendaylight.controller.usermanager.IUserManager;
 
 public class DaylightWebUtil {
-    private static String defaultName = GlobalConstants.DEFAULT.toString();
 
     /**
-     * Returns the container that this user is authorized to access. If the user is not authorized to the requested
-     * container, then this method will return the default container.
+     * Returns the access privilege the user has on the specified container
      *
-     * @param request - HttpServletRequest object to retrieve username
-     * @param container - requested container
-     * @param bundle - respective bundle
-     * @return container name if cleared, else it will always be 'default'
+     * @param userName
+     *            The user name
+     * @param container
+     *            The container name. If null, the default container will be assumed
+     * @param bundle
+     *            The bundle originating the request
+     * @return The access privilege the user is granted on the container
      */
-    public static String getAuthorizedContainer(HttpServletRequest request, String container, Object bundle) {
-        if (container == null) {
-            return defaultName;
+    public static Privilege getContainerPrivilege(String userName,
+            String container, Object bundle) {
+        // Derive the target resource
+        String resource = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Retrieve the Container Authorization service
+        IContainerAuthorization auth = (IContainerAuthorization) ServiceHelper
+                .getGlobalInstance(IContainerAuthorization.class, bundle);
+        if (auth != null) {
+            return auth.getResourcePrivilege(userName, resource);
         }
 
-        String username = request.getUserPrincipal().getName();
-        IContainerAuthorization containerAuthorization = (IContainerAuthorization)
-                ServiceHelper.getGlobalInstance(IContainerAuthorization.class, bundle);
-        if (containerAuthorization != null) {
-            Set<Resource> resources = containerAuthorization.getAllResourcesforUser(username);
-            for(Resource resource : resources) {
-                String name = (String) resource.getResource();
-                if(container.equals(name)) {
-                    return name;
+        /*
+         * Container Authorization service not available. We can only derive the
+         * access privilege to the default container based on user level
+         */
+        if (resource.equals(GlobalConstants.DEFAULT.toString())) {
+            IUserManager userManager = (IUserManager) ServiceHelper
+                    .getGlobalInstance(IUserManager.class, bundle);
+            if (userManager != null) {
+                switch (userManager.getUserLevel(userName)) {
+                case NETWORKADMIN:
+                    return Privilege.WRITE;
+                case NETWORKOPERATOR:
+                    return Privilege.READ;
+                default:
+                    return Privilege.NONE;
                 }
             }
         }
-        return defaultName;
+
+        return Privilege.NONE;
     }
 }
\ No newline at end of file
index 62b64a51849ea2ee08c4b9f43cffca8439bd5cad..31d743ee2308712d2b5df3d174b7e8ebdb89748c 100644 (file)
@@ -25,12 +25,11 @@ import java.util.Set;
 import javax.servlet.http.HttpServletRequest;
 
 import org.opendaylight.controller.configuration.IConfigurationAware;
-import org.opendaylight.controller.containermanager.IContainerAuthorization;
-import org.opendaylight.controller.sal.authorization.Resource;
-import org.opendaylight.controller.sal.authorization.UserLevel;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.core.Bandwidth;
 import org.opendaylight.controller.sal.core.Edge;
 import org.opendaylight.controller.sal.core.Host;
+import org.opendaylight.controller.sal.core.Name;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -47,9 +46,7 @@ import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Switch;
 import org.opendaylight.controller.switchmanager.SwitchConfig;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
-import org.opendaylight.controller.usermanager.IUserManager;
 import org.opendaylight.controller.web.DaylightWebUtil;
-import org.opendaylight.controller.web.IDaylightWeb;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -92,7 +89,15 @@ public class Topology implements IObjectReader, IConfigurationAware {
     @RequestMapping(value = "/visual.json", method = RequestMethod.GET)
     @ResponseBody
     public Collection<Map<String, Object>> getLinkData(@RequestParam(required = false) String container, HttpServletRequest request) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
+        if (privilege == Privilege.NONE) {
+            return null;
+        }
 
         ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
                 .getInstance(ITopologyManager.class, containerName, this);
@@ -191,7 +196,14 @@ public class Topology implements IObjectReader, IConfigurationAware {
                         break;
                     }
                 }
-                EdgeBean edge = new EdgeBean(link, bandwidth);
+                NodeConnector headNodeConnector = link.getHeadNodeConnector();
+                NodeConnector tailNodeConnector = link.getTailNodeConnector();
+
+                String headDescription = this.getNodeConnectorDescription(headNodeConnector, switchManager);
+                String tailDescription = this.getNodeConnectorDescription(tailNodeConnector, switchManager);
+                String headPortDescription = this.getNodeConnectorPortDescription(headNodeConnector, switchManager);
+                String tailPortDescription = this.getNodeConnectorPortDescription(tailNodeConnector, switchManager);
+                EdgeBean edge = new EdgeBean(link, bandwidth, headDescription, tailDescription, headPortDescription, tailPortDescription);
                 adjacencies.add(edge.out());
             }
 
@@ -254,11 +266,32 @@ public class Topology implements IObjectReader, IConfigurationAware {
     }
 
     protected NodeBean createNodeBean(String description, Node node) {
+        String name = this.getDescription(description, node);
+        return  new NodeBean(node.toString(), name, NodeType.NODE);
+    }
+
+    private String getDescription(String description, Node node) {
         String name = (description == null ||
-                        description.trim().isEmpty() ||
-                        description.equalsIgnoreCase("none"))?
-                                        node.toString() : description;
-                return  new NodeBean(node.toString(), name, NodeType.NODE);
+                description.trim().isEmpty() ||
+                description.equalsIgnoreCase("none"))?
+                                node.toString() : description;
+        return name;
+    }
+
+    private String getNodeConnectorDescription(NodeConnector nodeConnector, ISwitchManager switchManager) {
+        Node node = nodeConnector.getNode();
+        String description = switchManager.getNodeDescription(node);
+        String name = this.getDescription(description, node);
+        return name;
+    }
+
+    private String getNodeConnectorPortDescription(NodeConnector nodeConnector, ISwitchManager switchManager) {
+        Name ncName = (Name) switchManager.getNodeConnectorProp(nodeConnector, Name.NamePropName);
+        String nodeConnectorName = nodeConnector.getNodeConnectorIDString();
+        if (ncName != null) {
+            nodeConnectorName = ncName.getValue();
+        }
+        return nodeConnectorName;
     }
 
     @SuppressWarnings("unchecked")
@@ -384,11 +417,15 @@ public class Topology implements IObjectReader, IConfigurationAware {
     public Map<String, Object> post(@PathVariable String nodeId, @RequestParam(required = true) String x,
                 @RequestParam(required = true) String y, @RequestParam(required = false) String container,
                 HttpServletRequest request) {
-        if (!authorize(UserLevel.NETWORKADMIN, request)) {
-                return new HashMap<String, Object>(); // silently disregard new node position
-        }
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
 
-        String containerName = getAuthorizedContainer(request, container);
+        if (privilege != Privilege.WRITE) {
+            return new HashMap<String, Object>(); // silently disregard new node position
+        }
 
         String id = new String(nodeId);
 
@@ -465,36 +502,47 @@ public class Topology implements IObjectReader, IConfigurationAware {
                 data = new HashMap<String, String>();
         }
 
-        public EdgeBean(Edge link, Bandwidth bandwidth) {
-                this();
-                this.source = link.getHeadNodeConnector();
-                this.destination = link.getTailNodeConnector();
-
-                // data
-                data.put("$bandwidth", bandwidth.toString());
-                data.put("$color", bandwidthColor(bandwidth));
-                data.put("$nodeToPort", destination.getID().toString());
-                data.put("$nodeFromPort", source.getID().toString());
-                data.put("$descFrom", source.getNode().toString());
-                data.put("$descTo", destination.getNode().toString());
-                data.put("$nodeFromPortName", source.toString());
-                data.put("$nodeToPortName", destination.toString());
+        /**
+         * EdgeBean object that includes complete node description
+         *
+         * @param link
+         * @param bandwidth
+         * @param headDescription
+         * @param tailDescription
+         */
+        public EdgeBean(Edge link, Bandwidth bandwidth, String headDescription,
+                String tailDescription, String headPortDescription, String tailPortDescription) {
+            this();
+            this.source = link.getHeadNodeConnector();
+            this.destination = link.getTailNodeConnector();
+
+            // data
+            data.put("$bandwidth", bandwidth.toString());
+            data.put("$color", bandwidthColor(bandwidth));
+            data.put("$nodeToPort", destination.getID().toString());
+            data.put("$nodeFromPort", source.getID().toString());
+            data.put("$descFrom", headDescription);
+            data.put("$descTo", tailDescription);
+            data.put("$nodeFromPortName", source.toString());
+            data.put("$nodeToPortName", destination.toString());
+            data.put("$nodeFromPortDescription", headPortDescription);
+            data.put("$nodeToPortDescription", tailPortDescription);
         }
 
         public EdgeBean(NodeConnector connector, Long hostId) {
-                this();
-                this.source = null;
-                this.destination = connector;
-                this.hostId = hostId;
-
-                data.put("$bandwidth", "N/A");
-                data.put("$color", bandwidthColor(new Bandwidth(0)));
-                data.put("$nodeToPort", connector.getNodeConnectorIDString());
-                data.put("$nodeFromPort", connector.getNodeConnectorIDString());
-                data.put("$descTo", "");
-                data.put("$descFrom", "");
-                data.put("$nodeToPortName", "");
-                data.put("$nodeFromPortName", "");
+            this();
+            this.source = null;
+            this.destination = connector;
+            this.hostId = hostId;
+
+            data.put("$bandwidth", "N/A");
+            data.put("$color", bandwidthColor(new Bandwidth(0)));
+            data.put("$nodeToPort", connector.getNodeConnectorIDString());
+            data.put("$nodeFromPort", connector.getNodeConnectorIDString());
+            data.put("$descTo", "");
+            data.put("$descFrom", "");
+            data.put("$nodeToPortName", "");
+            data.put("$nodeFromPortName", "");
         }
 
         public Map<String, Object> out() {
@@ -539,51 +587,13 @@ public class Topology implements IObjectReader, IConfigurationAware {
         public static final String HOST = "host";
     }
 
-    private boolean authorize(UserLevel level, HttpServletRequest request) {
-        IUserManager userManager = (IUserManager) ServiceHelper
-                .getGlobalInstance(IUserManager.class, this);
-        if (userManager == null) {
-                return false;
-        }
-
-        String username = request.getUserPrincipal().getName();
-        UserLevel userLevel = userManager.getUserLevel(username);
-        if (userLevel.toNumber() <= level.toNumber()) {
-                return true;
-        }
-        return false;
-    }
-
-    private String getAuthorizedContainer(HttpServletRequest request, String container) {
-        String username = request.getUserPrincipal().getName();
-        IContainerAuthorization containerAuthorization = (IContainerAuthorization) ServiceHelper.
-                        getGlobalInstance(IContainerAuthorization.class, this);
-        if (containerAuthorization != null) {
-                Set<Resource> resources = containerAuthorization.getAllResourcesforUser(username);
-                if (authorizeContainer(container, resources)) {
-                        return container;
-                }
-        }
-
-        return GlobalConstants.DEFAULT.toString();
-    }
-
-    private boolean authorizeContainer(String container, Set<Resource> resources) {
-        for(Resource resource : resources) {
-                String containerName = (String) resource.getResource();
-                if (containerName.equals(container)) {
-                        return true;
-                }
-        }
-
-        return false;
-    }
-
     @SuppressWarnings("unchecked")
         private void loadConfiguration() {
         ObjectReader objReader = new ObjectReader();
         metaCache = (Map<String, Map<String, Map<String, Object>>>) objReader.read(this, topologyWebFileName);
-        if (metaCache == null) metaCache = new HashMap<String, Map<String, Map<String, Object>>>();
+        if (metaCache == null) {
+            metaCache = new HashMap<String, Map<String, Map<String, Object>>>();
+        }
     }
 
     @Override
index bde4152f5bdfd59c3631a5a80fbaccfd5011343a..f5fda3d1bc8fe245323d3cb8666a185e9753472a 100644 (file)
@@ -14,6 +14,7 @@ import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import javax.servlet.http.HttpServletRequest;
@@ -21,6 +22,7 @@ import javax.servlet.http.HttpServletRequest;
 import org.opendaylight.controller.sal.action.Action;
 import org.opendaylight.controller.sal.action.Output;
 import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.authorization.Privilege;
 import org.opendaylight.controller.sal.authorization.UserLevel;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
@@ -50,10 +52,22 @@ import org.springframework.web.bind.annotation.ResponseBody;
 @RequestMapping("/")
 public class Troubleshoot implements IDaylightWeb {
     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
+    private static final List<String> flowStatsColumnNames = Arrays.asList("Node", "In Port",
+            "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
+            "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
+            "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
+            "Priority");
+    private static final List<String> portStatsColumnNames = Arrays.asList("Node Connector",
+            "Rx Pkts", "Tx Pkts", "Rx Bytes", "Tx Bytes", "Rx Drops",
+            "Tx Drops", "Rx Errs", "Tx Errs", "Rx Frame Errs",
+            "Rx OverRun Errs", "Rx CRC Errs", "Collisions");
+    private static final List<String> nodesColumnNames = Arrays.asList("Node", "Node ID", "Statistics");
+    private static final List<String> nodeStatsColumnNames = Arrays.asList("Node", "Node ID", "Statistics");
     private final String WEB_NAME = "Troubleshoot";
     private final String WEB_ID = "troubleshoot";
     private final short WEB_ORDER = 4;
 
+
     public Troubleshoot() {
         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
     }
@@ -81,30 +95,29 @@ public class Troubleshoot implements IDaylightWeb {
     @RequestMapping(value = "/existingNodes", method = RequestMethod.GET)
     @ResponseBody
     public TroubleshootingJsonBean getExistingNodes(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
-        List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
-        Set<Node> nodeSet = null;
-        if (switchManager != null) {
-            nodeSet = switchManager.getNodes();
-        }
-        if (nodeSet != null) {
-            for (Node node : nodeSet) {
-                HashMap<String, String> device = new HashMap<String, String>();
-                device.put("nodeName", switchManager.getNodeDescription(node));
-                device.put("nodeId", node.toString());
-                lines.add(device);
+        List<Map<String, String>> lines = new ArrayList<Map<String, String>>();
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
+                    .getInstance(ISwitchManager.class, containerName, this);
+            Set<Node> nodeSet = (switchManager != null) ? switchManager.getNodes() : null;
+            if (nodeSet != null) {
+                for (Node node : nodeSet) {
+                    Map<String, String> device = new HashMap<String, String>();
+                    device.put("nodeName", switchManager.getNodeDescription(node));
+                    device.put("nodeId", node.toString());
+                    lines.add(device);
+                }
             }
         }
-        TroubleshootingJsonBean result = new TroubleshootingJsonBean();
 
-        List<String> guiFieldNames = new ArrayList<String>();
-        guiFieldNames.add("Node");
-        guiFieldNames.add("Node ID");
-        guiFieldNames.add("Statistics");
-
-        result.setColumnNames(guiFieldNames);
+        TroubleshootingJsonBean result = new TroubleshootingJsonBean();
+        result.setColumnNames(nodesColumnNames);
         result.setNodeData(lines);
         return result;
     }
@@ -112,35 +125,34 @@ public class Troubleshoot implements IDaylightWeb {
     @RequestMapping(value = "/uptime", method = RequestMethod.GET)
     @ResponseBody
     public TroubleshootingJsonBean getUptime(HttpServletRequest request, @RequestParam(required = false) String container) {
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
-        List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
-        Set<Node> nodeSet = null;
-        if (switchManager != null) {
-            nodeSet = switchManager.getNodes();
-        }
-        if (nodeSet != null) {
-            for (Node node : nodeSet) {
-                HashMap<String, String> device = new HashMap<String, String>();
-                device.put("nodeName", switchManager.getNodeDescription(node));
-                device.put("nodeId", node.toString());
-                TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
-                        node, TimeStamp.TimeStampPropName);
-                Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
-                String date = (time == 0) ? "" : (new Date(time)).toString();
-                device.put("connectedSince", date);
-                lines.add(device);
+        List<Map<String, String>> lines = new ArrayList<Map<String, String>>();
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
+                    .getInstance(ISwitchManager.class, containerName, this);
+            Set<Node> nodeSet = (switchManager != null) ? switchManager.getNodes() : null;
+            if (nodeSet != null) {
+                for (Node node : nodeSet) {
+                    Map<String, String> device = new HashMap<String, String>();
+                    device.put("nodeName", switchManager.getNodeDescription(node));
+                    device.put("nodeId", node.toString());
+                    TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
+                            node, TimeStamp.TimeStampPropName);
+                    Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
+                    String date = (time == 0) ? "" : (new Date(time)).toString();
+                    device.put("connectedSince", date);
+                    lines.add(device);
+                }
             }
         }
-        TroubleshootingJsonBean result = new TroubleshootingJsonBean();
 
-        List<String> guiFieldNames = new ArrayList<String>();
-        guiFieldNames.add("Node");
-        guiFieldNames.add("Node ID");
-        guiFieldNames.add("Connected");
-
-        result.setColumnNames(guiFieldNames);
+        TroubleshootingJsonBean result = new TroubleshootingJsonBean();
+        result.setColumnNames(nodeStatsColumnNames);
         result.setNodeData(lines);
         return result;
     }
@@ -150,24 +162,27 @@ public class Troubleshoot implements IDaylightWeb {
     public TroubleshootingJsonBean getFlowStats(
             @RequestParam("nodeId") String nodeId,
             HttpServletRequest request, @RequestParam(required = false) String container) {
-        Node node = Node.fromString(nodeId);
-        List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
-                .getInstance(IStatisticsManager.class, containerName, this);
-
-        List<FlowOnNode> statistics = statisticsManager.getFlows(node);
-        for (FlowOnNode stats : statistics) {
-            cells.add(this.convertFlowStatistics(node, stats, containerName));
+        List<Map<String, String>> cells = new ArrayList<Map<String, String>>();
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
+                    .getInstance(IStatisticsManager.class, containerName, this);
+            if (statisticsManager != null) {
+                Node node = Node.fromString(nodeId);
+                List<FlowOnNode> statistics = statisticsManager.getFlows(node);
+                for (FlowOnNode stats : statistics) {
+                    cells.add(this.convertFlowStatistics(node, stats, containerName));
+                }
+            }
         }
-        List<String> columnNames = new ArrayList<String>();
-        columnNames.addAll(Arrays.asList(new String[] { "Node", "In Port",
-                "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
-                "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
-                "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
-                "Priority" }));
+
         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
-        result.setColumnNames(columnNames);
+        result.setColumnNames(flowStatsColumnNames);
         result.setNodeData(cells);
         return result;
     }
@@ -177,30 +192,35 @@ public class Troubleshoot implements IDaylightWeb {
     public TroubleshootingJsonBean getPortStats(
             @RequestParam("nodeId") String nodeId,
             HttpServletRequest request, @RequestParam(required = false) String container) {
-        Node node = Node.fromString(nodeId);
-        List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
-        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
-        IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
-                .getInstance(IStatisticsManager.class, containerName, this);
-        List<NodeConnectorStatistics> statistics = statisticsManager
-                .getNodeConnectorStatistics(node);
-        for (NodeConnectorStatistics stats : statistics) {
-            cells.add(this.convertPortsStatistics(stats));
+        List<Map<String, String>> cells = new ArrayList<Map<String, String>>();
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
+
+        // Derive the privilege this user has on the current container
+        String userName = request.getUserPrincipal().getName();
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
+
+        if (privilege != Privilege.NONE) {
+            IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
+                    .getInstance(IStatisticsManager.class, containerName, this);
+            if (statisticsManager != null) {
+                Node node = Node.fromString(nodeId);
+                List<NodeConnectorStatistics> statistics = statisticsManager
+                        .getNodeConnectorStatistics(node);
+                for (NodeConnectorStatistics stats : statistics) {
+                    cells.add(this.convertPortsStatistics(stats));
+                }
+            }
         }
+
         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
-        List<String> columnNames = new ArrayList<String>();
-        columnNames.addAll(Arrays.asList(new String[] { "Node Connector",
-                "Rx Pkts", "Tx Pkts", "Rx Bytes", "Tx Bytes", "Rx Drops",
-                "Tx Drops", "Rx Errs", "Tx Errs", "Rx Frame Errs",
-                "Rx OverRun Errs", "Rx CRC Errs", "Collisions" }));
-        result.setColumnNames(columnNames);
+        result.setColumnNames(portStatsColumnNames);
         result.setNodeData(cells);
         return result;
     }
 
-    private HashMap<String, String> convertPortsStatistics(
+    private Map<String, String> convertPortsStatistics(
             NodeConnectorStatistics ncStats) {
-        HashMap<String, String> row = new HashMap<String, String>();
+        Map<String, String> row = new HashMap<String, String>();
 
         row.put("nodeConnector",
                 String.valueOf(ncStats.getNodeConnector().toString()));
@@ -223,10 +243,10 @@ public class Troubleshoot implements IDaylightWeb {
         return row;
     }
 
-    private HashMap<String, String> convertFlowStatistics(Node node,
+    private Map<String, String> convertFlowStatistics(Node node,
             FlowOnNode flowOnNode,
             String containerName) {
-        HashMap<String, String> row = new HashMap<String, String>();
+        Map<String, String> row = new HashMap<String, String>();
         Flow flow = flowOnNode.getFlow();
         Match match = flow.getMatch();
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
index 1030c49511b0be53a6c48d25a178f28b77fde039..3c9a8b0b266be9174e4c848c2dcc20ecb6591d90 100644 (file)
@@ -9,12 +9,12 @@
 
 package org.opendaylight.controller.troubleshoot.web;
 
-import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 public class TroubleshootingJsonBean {
     private List<String> columnNames;
-    private List<HashMap<String, String>> nodeData;
+    private List<Map<String, String>> nodeData;
 
     public List<String> getColumnNames() {
         return columnNames;
@@ -24,11 +24,11 @@ public class TroubleshootingJsonBean {
         this.columnNames = columnNames;
     }
 
-    public List<HashMap<String, String>> getNodeData() {
+    public List<Map<String, String>> getNodeData() {
         return nodeData;
     }
 
-    public void setNodeData(List<HashMap<String, String>> nodeData) {
+    public void setNodeData(List<Map<String, String>> nodeData) {
         this.nodeData = nodeData;
     }
 }