Add generic container logic to web bundles 10/310/1
authorAndrew Kim <andrekim@cisco.com>
Tue, 7 May 2013 01:21:11 +0000 (18:21 -0700)
committerAndrew Kim <andrekim@cisco.com>
Tue, 7 May 2013 01:21:11 +0000 (18:21 -0700)
Signed-off-by: Andrew Kim <andrekim@cisco.com>
opendaylight/web/devices/src/main/java/org/opendaylight/controller/devices/web/Devices.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 [new file with mode: 0644]
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

index c7ba7aa..1102a63 100644 (file)
@@ -21,6 +21,7 @@ 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;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -55,7 +56,6 @@ public class Devices implements IDaylightWeb {
     private final String WEB_NAME = "Devices";
     private final String WEB_ID = "devices";
     private final short WEB_ORDER = 1;
-    private final String containerName = GlobalConstants.DEFAULT.toString();
 
     public Devices() {
         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
@@ -83,8 +83,9 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodesLearnt", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getNodesLearnt() {
+    public DevicesJsonBean getNodesLearnt(HttpServletRequest request, @RequestParam(required = false) String container) {
         Gson gson = new Gson();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
@@ -175,12 +176,13 @@ public class Devices implements IDaylightWeb {
             @RequestParam("nodeId") String nodeId,
             @RequestParam("tier") String tier,
             @RequestParam("operationMode") String operationMode,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -199,8 +201,9 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getStaticRoutes() {
+    public DevicesJsonBean getStaticRoutes(HttpServletRequest request, @RequestParam(required = false) String container) {
         Gson gson = new Gson();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                 .getInstance(IForwardingStaticRouting.class, containerName,
                         this);
@@ -230,12 +233,14 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean addStaticRoute(
             @RequestParam("routeName") String routeName,
             @RequestParam("staticRoute") String staticRoute,
-            @RequestParam("nextHop") String nextHop, HttpServletRequest request) {
+            @RequestParam("nextHop") String nextHop,
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean result = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                     .getInstance(IForwardingStaticRouting.class, containerName,
@@ -263,12 +268,13 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteStaticRoute(
             @RequestParam("routesToDelete") String routesToDelete,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
                     .getInstance(IForwardingStaticRouting.class, containerName,
@@ -297,9 +303,10 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnets", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getSubnetGateways() {
+    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);
         for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
@@ -320,12 +327,13 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean addSubnetGateways(
             @RequestParam("gatewayName") String gatewayName,
             @RequestParam("gatewayIPAddress") String gatewayIPAddress,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -350,12 +358,13 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteSubnetGateways(
             @RequestParam("gatewaysToDelete") String gatewaysToDelete,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -382,12 +391,14 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean addSubnetGatewayPort(
             @RequestParam("portsName") String portsName,
             @RequestParam("ports") String ports,
-            @RequestParam("nodeId") String nodeId, HttpServletRequest request) {
+            @RequestParam("nodeId") String nodeId,
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -414,12 +425,13 @@ public class Devices implements IDaylightWeb {
     public StatusJsonBean deleteSubnetGatewayPort(
             @RequestParam("gatewayName") String gatewayName,
             @RequestParam("nodePort") String nodePort,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         try {
             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                     .getInstance(ISwitchManager.class, containerName, this);
@@ -443,9 +455,10 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
     @ResponseBody
-    public DevicesJsonBean getSpanPorts() {
+    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);
         for (SpanConfig conf : switchManager.getSpanConfigList()) {
@@ -463,7 +476,7 @@ public class Devices implements IDaylightWeb {
                     config.put(name, config_data.get(name));
                     // Add switch name value (non-configuration field)
                     config.put("nodeName",
-                            getNodeDesc(config_data.get("nodeId")));
+                            getNodeDesc(config_data.get("nodeId"), containerName));
                 }
                 config.put("json", config_json);
                 spanConfigs.add(config);
@@ -479,7 +492,8 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodeports")
     @ResponseBody
-    public Map<String, Object> getNodePorts() {
+    public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null)
@@ -511,7 +525,7 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean addSpanPort(
             @RequestParam("jsonData") String jsonData,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
@@ -519,6 +533,7 @@ public class Devices implements IDaylightWeb {
         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);
@@ -542,7 +557,7 @@ public class Devices implements IDaylightWeb {
     @ResponseBody
     public StatusJsonBean deleteSpanPorts(
             @RequestParam("spanPortsToDelete") String spanPortsToDelete,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!authorize(UserLevel.NETWORKADMIN, request)) {
             return unauthorizedMessage();
         }
@@ -550,6 +565,7 @@ public class Devices implements IDaylightWeb {
         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("###");
@@ -575,7 +591,7 @@ public class Devices implements IDaylightWeb {
         return resultBean;
     }
 
-    private String getNodeDesc(String nodeId) {
+    private String getNodeDesc(String nodeId, String containerName) {
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         String description = "";
index 0254ab3..7cb2b3a 100644 (file)
@@ -22,7 +22,6 @@ 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;
@@ -30,6 +29,7 @@ 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;
 import org.springframework.web.bind.annotation.PathVariable;
@@ -47,7 +47,6 @@ public class Flows implements IDaylightWeb {
     private static final String WEB_NAME = "Flows";
     private static final String WEB_ID = "flows";
     private static final short WEB_ORDER = 2;
-    private final String containerName = GlobalConstants.DEFAULT.toString();
 
     public Flows() {
         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
@@ -75,7 +74,9 @@ public class Flows implements IDaylightWeb {
 
     @RequestMapping(value = "/main")
     @ResponseBody
-    public Set<Map<String, Object>> getFlows() {
+    public Set<Map<String, Object>> getFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        
         // fetch frm
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, containerName, this);
@@ -110,7 +111,9 @@ public class Flows implements IDaylightWeb {
 
     @RequestMapping(value = "/node-ports")
     @ResponseBody
-    public Map<String, Object> getNodePorts() {
+    public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
@@ -155,14 +158,16 @@ public class Flows implements IDaylightWeb {
 
     @RequestMapping(value = "/node-flows")
     @ResponseBody
-    public Map<String, Object> getNodeFlows() {
+    public Map<String, Object> getNodeFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+        
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
                 .getInstance(ISwitchManager.class, containerName, this);
         if (switchManager == null) {
             return null;
         }
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
-                .getInstance(IForwardingRulesManager.class, "default", this);
+                .getInstance(IForwardingRulesManager.class, containerName, this);
         if (frm == null) {
             return null;
         }
@@ -192,10 +197,12 @@ public class Flows implements IDaylightWeb {
     public String actionFlow(@RequestParam(required = true) String action,
             @RequestParam(required = false) String body,
             @RequestParam(required = true) String nodeId,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!isUserAuthorized(UserLevel.NETWORKADMIN, request)) {
             return "Operation not authorized";
         }
+        
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
 
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, containerName, this);
@@ -221,11 +228,12 @@ public class Flows implements IDaylightWeb {
     public String removeFlow(@PathVariable("nodeId") String nodeId,
             @PathVariable("name") String name,
             @RequestParam(required = true) String action,
-            HttpServletRequest request) {
+            HttpServletRequest request, @RequestParam(required = false) String container) {
         if (!isUserAuthorized(UserLevel.NETWORKADMIN, request)) {
-
             return "Operation not authorized";
         }
+        
+        String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
 
         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
                 .getInstance(IForwardingRulesManager.class, containerName, this);
diff --git a/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java b/opendaylight/web/root/src/main/java/org/opendaylight/controller/web/DaylightWebUtil.java
new file mode 100644 (file)
index 0000000..ee8284e
--- /dev/null
@@ -0,0 +1,43 @@
+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.utils.GlobalConstants;
+import org.opendaylight.controller.sal.utils.ServiceHelper;
+
+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.
+     * 
+     * @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'
+     */
+    public static String getAuthorizedContainer(HttpServletRequest request, String container, Object bundle) {
+        if (container == null) {
+            return defaultName;
+        }
+        
+        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;
+                }
+            }
+        }
+        return defaultName;
+    }
+}
\ No newline at end of file
index af25abd..3e25110 100644 (file)
@@ -21,21 +21,25 @@ 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.UserLevel;
 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.Node;
+import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.Property;
-import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.packet.address.EthernetAddress;
+import org.opendaylight.controller.sal.utils.GlobalConstants;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 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.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -51,13 +55,14 @@ import edu.uci.ics.jung.graph.SparseMultigraph;
 @RequestMapping("/")
 public class Topology {
 
-    protected Map<String, Map<String, Object>> cache = new HashMap<String, Map<String, Object>>();
+    protected Map<String, Map<String, Map<String, Object>>> metaCache = new HashMap<String, Map<String, Map<String, Object>>>();
     protected Map<String, Map<String, Object>> stagedNodes;
     protected Map<String, Map<String, Object>> newNodes;
-    protected Integer nodeHash = null;
-    protected Integer hostHash = null;
-    protected Integer nodeSingleHash = null;
-    protected Integer nodeConfigurationHash = null;
+    
+    protected Map<String, Integer> metaNodeHash = new HashMap<String, Integer>();
+    protected Map<String, Integer> metaHostHash = new HashMap<String, Integer>();
+    protected Map<String, Integer> metaNodeSingleHash = new HashMap<String, Integer>();
+    protected Map<String, Integer> metaNodeConfigurationHash = new HashMap<String, Integer>();
     
     /**
      * Topology of nodes and hosts in the network in JSON format.
@@ -68,13 +73,19 @@ public class Topology {
      */
     @RequestMapping(value = "/visual.json", method = RequestMethod.GET)
     @ResponseBody
-    public Collection<Map<String, Object>> getLinkData() {
+    public Collection<Map<String, Object>> getLinkData(@RequestParam(required = false) String container, HttpServletRequest request) {
+       String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
+       
         ITopologyManager topologyManager = (ITopologyManager) ServiceHelper
-                .getInstance(ITopologyManager.class, "default", this);
-        if (topologyManager == null) return null;
+                .getInstance(ITopologyManager.class, containerName, this);
+        if (topologyManager == null) {
+               return null;
+        }
         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, "default", this);
-        if (switchManager == null) return null;
+                .getInstance(ISwitchManager.class, containerName, this);
+        if (switchManager == null) {
+               return null;
+        }
         
         Map<Node, Set<Edge>> nodeEdges = topologyManager.getNodeEdges();
         Map<Node, Set<NodeConnector>> hostEdges = topologyManager
@@ -88,35 +99,45 @@ public class Topology {
                switchConfigurations.add(config);
         }
         
+        // initialize cache if needed
+        if (!metaCache.containsKey(containerName)) {
+               metaCache.put(containerName, new HashMap<String, Map<String, Object>>());
+               // initialize hashes
+               metaNodeHash.put(containerName, null);
+               metaHostHash.put(containerName, null);
+               metaNodeSingleHash.put(containerName, null);
+               metaNodeConfigurationHash.put(containerName, null);
+        }
+        
         // return cache if topology hasn't changed
         if (
-               (nodeHash != null && hostHash != null && nodeSingleHash != null && nodeConfigurationHash != null) &&
-               nodeHash == nodeEdges.hashCode() && hostHash == hostEdges.hashCode() && nodeSingleHash == nodes.hashCode() && nodeConfigurationHash == switchConfigurations.hashCode()
+               (metaNodeHash.get(containerName) != null && metaHostHash.get(containerName) != null && metaNodeSingleHash.get(containerName) != null && metaNodeConfigurationHash.get(containerName) != null) &&
+               metaNodeHash.get(containerName).equals(nodeEdges.hashCode()) && metaHostHash.get(containerName).equals(hostEdges.hashCode()) && metaNodeSingleHash.get(containerName).equals(nodes.hashCode()) && metaNodeConfigurationHash.get(containerName).equals(switchConfigurations.hashCode())
         ) {
-               return cache.values();
+               return metaCache.get(containerName).values();
         }
         
         // cache has changed, we must assign the new values
-        nodeHash = nodeEdges.hashCode();
-        hostHash = hostEdges.hashCode();
-        nodeSingleHash = nodes.hashCode();
-        nodeConfigurationHash = switchConfigurations.hashCode();
+        metaNodeHash.put(containerName, nodeEdges.hashCode());
+        metaHostHash.put(containerName, hostEdges.hashCode());
+        metaNodeSingleHash.put(containerName, nodes.hashCode());
+        metaNodeConfigurationHash.put(containerName, switchConfigurations.hashCode());
         
         stagedNodes = new HashMap<String, Map<String, Object>>();
         newNodes = new HashMap<String, Map<String, Object>>();
 
         // nodeEdges addition
-        addNodes(nodeEdges, topologyManager, switchManager);
+        addNodes(nodeEdges, topologyManager, switchManager, containerName);
 
         // single nodes addition
-        addSingleNodes(nodes, switchManager);
+        addSingleNodes(nodes, switchManager, containerName);
         
         // hostNodes addition
-        addHostNodes(hostEdges, topologyManager);
+        addHostNodes(hostEdges, topologyManager, containerName);
         
-        repositionTopology();
+        repositionTopology(containerName);
         
-        return cache.values();
+        return metaCache.get(containerName).values();
     }
 
     /**
@@ -126,21 +147,20 @@ public class Topology {
      * @param topology - the topology instance
      */
     private void addNodes(Map<Node, Set<Edge>> nodeEdges,
-            ITopologyManager topology, ISwitchManager switchManager) {
+            ITopologyManager topology, ISwitchManager switchManager, String containerName) {           
         Bandwidth bandwidth = new Bandwidth(0);
         Map<Edge, Set<Property>> properties = topology.getEdges();
         
         for (Map.Entry<Node, Set<Edge>> e : nodeEdges.entrySet()) {
             Node n = e.getKey();
+            String description = switchManager.getNodeDescription(n);
+            NodeBean node = createNodeBean(description, n);
             
             // skip production node
             if (nodeIgnore(n)) {
                 continue;
             }
             
-            String description = switchManager.getNodeDescription(n);
-            NodeBean node = createNodeBean(description, n);
-            
             List<Map<String, Object>> adjacencies = new LinkedList<Map<String, Object>>();
             Set<Edge> links = e.getValue();
             for (Edge link : links) {
@@ -158,9 +178,9 @@ public class Topology {
             }
             
             node.setLinks(adjacencies);
-            if (cache.containsKey(node.id())) {
+            if (metaCache.get(containerName).containsKey(node.id())) {
                // retrieve node from cache
-               Map<String, Object> nodeEntry = cache.get(node.id());
+               Map<String, Object> nodeEntry = metaCache.get(containerName).get(node.id());
 
                        Map<String, String> data = (Map<String, String>) nodeEntry.get("data");
                        data.put("$desc", description);
@@ -224,26 +244,28 @@ public class Topology {
     }
     
     @SuppressWarnings("unchecked")
-       private void addSingleNodes(List<Switch> nodes, ISwitchManager switchManager) {
-       if (nodes == null) return;
+       private void addSingleNodes(List<Switch> nodes, ISwitchManager switchManager, String containerName) {
+       if (nodes == null) {
+               return;
+       }
        for (Switch sw : nodes) {
                Node n = sw.getNode();
                
                // skip production node
-                if (nodeIgnore(n)) {
-                    continue;
-                }
+               if (nodeIgnore(n)) {
+                   continue;
+               }
 
                String description = switchManager.getNodeDescription(n);
                
-               if ((stagedNodes.containsKey(n.toString()) && cache.containsKey(n.toString())) || newNodes.containsKey(n.toString())) {
+               if ((stagedNodes.containsKey(n.toString()) && metaCache.get(containerName).containsKey(n.toString())) || newNodes.containsKey(n.toString())) {
                        continue;
                }
                NodeBean node = createNodeBean(description, n);
                
                // FIXME still doesn't display standalone node when last remaining link is removed
-               if (cache.containsKey(node.id()) && !stagedNodes.containsKey(node.id())) {
-                       Map<String, Object> nodeEntry = cache.get(node.id());
+               if (metaCache.get(containerName).containsKey(node.id()) && !stagedNodes.containsKey(node.id())) {
+                       Map<String, Object> nodeEntry = metaCache.get(containerName).get(node.id());
                                Map<String, String> data = (Map<String, String>) nodeEntry.get("data");
                        data.put("$desc", description);
                        nodeEntry.put("data", data);
@@ -261,7 +283,7 @@ public class Topology {
      * @param topology - topology instance
      */
     private void addHostNodes(Map<Node, Set<NodeConnector>> hostEdges,
-            ITopologyManager topology) {
+            ITopologyManager topology, String containerName) {
         for (Map.Entry<Node, Set<NodeConnector>> e : hostEdges.entrySet()) {
             for (NodeConnector connector : e.getValue()) {
                 Host host = topology.getHostAttachedToNodeConnector(connector);
@@ -281,8 +303,8 @@ public class Topology {
                 adjacencies.add(edge.out());
                 hostBean.setLinks(adjacencies);
                 
-                if (cache.containsKey(hostId)) {
-                       Map<String, Object> hostEntry = cache.get(hostId);
+                if (metaCache.get(containerName).containsKey(hostId)) {
+                       Map<String, Object> hostEntry = metaCache.get(containerName).get(hostId);
                        hostEntry.put("adjacencies", adjacencies);
                        stagedNodes.put(hostId, hostEntry);
                 } else {
@@ -295,12 +317,14 @@ public class Topology {
     /**
      * Re-position nodes in circular layout
      */
-    private void repositionTopology() {
+    private void repositionTopology(String containerName) {
         Graph<String, String> graph = new SparseMultigraph<String, String>();
-        cache.clear();
-        cache.putAll(stagedNodes);
-        cache.putAll(newNodes);
-        for (Map<String, Object> on : cache.values()) {
+        
+        metaCache.get(containerName).clear();
+        metaCache.get(containerName).putAll(stagedNodes);
+        metaCache.get(containerName).putAll(newNodes);
+        
+        for (Map<String, Object> on : metaCache.get(containerName).values()) {
             graph.addVertex(on.toString());
 
             List<Map<String, Object>> adjacencies = (List<Map<String, Object>>) on.get("adjacencies");
@@ -313,7 +337,7 @@ public class Topology {
             }
         }
         
-        CircleLayout<String,String> layout = new CircleLayout<String,String>(graph);
+        CircleLayout<String, String> layout = new CircleLayout<String, String>(graph);
         layout.setSize(new Dimension(1200, 365));
         for (Map.Entry<String, Map<String, Object>> v : newNodes.entrySet()) {
             Double x = layout.transform(v.getKey()).getX();
@@ -338,17 +362,21 @@ public class Topology {
     @RequestMapping(value = "/node/{nodeId}", method = RequestMethod.POST)
     @ResponseBody
     public Map<String, Object> post(@PathVariable String nodeId, @RequestParam(required = true) String x,
-               @RequestParam(required = true) String y, HttpServletRequest request) {
+               @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 = getAuthorizedContainer(request, container);
+       
         String id = new String(nodeId);
         
-        if (!cache.containsKey(id))
+        if (!metaCache.get(containerName).containsKey(id)) {
             return null;
+        }
 
-        Map<String, Object> node = cache.get(id);
+        Map<String, Object> node = metaCache.get(containerName).get(id);
         Map<String, String> data = (Map<String, String>) node.get("data");
 
         data.put("$x", x);
@@ -505,4 +533,29 @@ public class Topology {
         }
         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;
+    }
+}
\ No newline at end of file
index dfa2107..f145c56 100644 (file)
@@ -16,6 +16,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Set;
 
+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;
@@ -36,6 +38,7 @@ import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.ServiceHelper;
 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
+import org.opendaylight.controller.web.DaylightWebUtil;
 import org.opendaylight.controller.web.IDaylightWeb;
 import org.springframework.stereotype.Controller;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -50,7 +53,6 @@ public class Troubleshoot implements IDaylightWeb {
     private final String WEB_NAME = "Troubleshoot";
     private final String WEB_ID = "troubleshoot";
     private final short WEB_ORDER = 4;
-    private final String containerName = GlobalConstants.DEFAULT.toString();
 
     public Troubleshoot() {
         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
@@ -78,7 +80,8 @@ public class Troubleshoot implements IDaylightWeb {
 
     @RequestMapping(value = "/existingNodes", method = RequestMethod.GET)
     @ResponseBody
-    public TroubleshootingJsonBean getExistingNodes() {
+    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>>();
@@ -108,7 +111,8 @@ public class Troubleshoot implements IDaylightWeb {
 
     @RequestMapping(value = "/uptime", method = RequestMethod.GET)
     @ResponseBody
-    public TroubleshootingJsonBean getUptime() {
+    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>>();
@@ -144,15 +148,17 @@ public class Troubleshoot implements IDaylightWeb {
     @RequestMapping(value = "/flowStats", method = RequestMethod.GET)
     @ResponseBody
     public TroubleshootingJsonBean getFlowStats(
-            @RequestParam("nodeId") String nodeId) {
+            @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));
+            cells.add(this.convertFlowStatistics(node, stats, containerName));
         }
         List<String> columnNames = new ArrayList<String>();
         columnNames.addAll(Arrays.asList(new String[] { "Node", "In Port",
@@ -169,9 +175,11 @@ public class Troubleshoot implements IDaylightWeb {
     @RequestMapping(value = "/portStats", method = RequestMethod.GET)
     @ResponseBody
     public TroubleshootingJsonBean getPortStats(
-            @RequestParam("nodeId") String nodeId) {
+            @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
@@ -216,7 +224,8 @@ public class Troubleshoot implements IDaylightWeb {
     }
 
     private HashMap<String, String> convertFlowStatistics(Node node,
-            FlowOnNode flowOnNode) {
+            FlowOnNode flowOnNode,
+            String containerName) {
         HashMap<String, String> row = new HashMap<String, String>();
         Flow flow = flowOnNode.getFlow();
         Match match = flow.getMatch();