Merge "Bug:129 Connection Manager Dashlet"
[controller.git] / opendaylight / web / devices / src / main / java / org / opendaylight / controller / devices / web / Devices.java
index e6a785f5868044bb4c82831225dd509e04abb92b..91261f6499fe6092595117d9f90e1eb967f4003a 100644 (file)
@@ -8,8 +8,11 @@
 
 package org.opendaylight.controller.devices.web;
 
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
@@ -21,10 +24,12 @@ import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.codehaus.jackson.map.ObjectMapper;
+import org.opendaylight.controller.connectionmanager.IConnectionManager;
 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.connection.ConnectionConstants;
 import org.opendaylight.controller.sal.core.Config;
 import org.opendaylight.controller.sal.core.Description;
 import org.opendaylight.controller.sal.core.ForwardingMode;
@@ -36,8 +41,10 @@ import org.opendaylight.controller.sal.core.State;
 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.NetUtils;
 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.sal.utils.TierHelper;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.SpanConfig;
@@ -47,20 +54,22 @@ import org.opendaylight.controller.switchmanager.SwitchConfig;
 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;
 import org.springframework.web.bind.annotation.RequestMethod;
 import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.ResponseBody;
 
 import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
 
 @Controller
 @RequestMapping("/")
 public class Devices implements IDaylightWeb {
     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
-    private final String WEB_NAME = "Devices";
-    private final String WEB_ID = "devices";
-    private final short WEB_ORDER = 1;
+    private static final String WEB_NAME = "Devices";
+    private static final String WEB_ID = "devices";
+    private static final short WEB_ORDER = 1;
 
     public Devices() {
         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
@@ -88,11 +97,9 @@ 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 = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Derive the privilege this user has on the current container
         String userName = request.getUserPrincipal().getName();
@@ -115,14 +122,21 @@ public class Devices implements IDaylightWeb {
                 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber) + " (Tier-" + tierNumber + ")");
                 nodeDatum.put("tier", tierNumber + "");
                 String modeStr = "0";
-                ForwardingMode mode = (ForwardingMode) switchManager.getNodeProp(node, ForwardingMode.name);
+                ForwardingMode mode = null;
+                if (!containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                    ISwitchManager switchManagerDefault = (ISwitchManager) ServiceHelper.getInstance(
+                            ISwitchManager.class, GlobalConstants.DEFAULT.toString(), this);
+                    mode = (ForwardingMode) switchManagerDefault.getNodeProp(node, ForwardingMode.name);
+                } else {
+                    mode = (ForwardingMode) switchManager.getNodeProp(node, ForwardingMode.name);
+                }
                 if (mode != null) {
                     modeStr = String.valueOf(mode.getValue());
                 }
                 nodeDatum.put("mode", modeStr);
 
                 nodeDatum.put("json", gson.toJson(nodeDatum));
-                nodeDatum.put("mac", HexEncode.bytesToHexString(device.getDataLayerAddress()));
+                nodeDatum.put("mac", HexEncode.bytesToHexStringFormat(device.getDataLayerAddress()));
                 StringBuffer sb1 = new StringBuffer();
                 Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
                 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
@@ -131,45 +145,35 @@ public class Devices implements IDaylightWeb {
                     for (NodeConnector nodeConnector : nodeConnectorSet) {
                         String nodeConnectorNumberToStr = nodeConnector.getID().toString();
                         Name ncName = ((Name) switchManager.getNodeConnectorProp(nodeConnector, Name.NamePropName));
-                        Config portStatus = ((Config) switchManager
-                                .getNodeConnectorProp(nodeConnector,
-                                        Config.ConfigPropName));
-                        State portState = ((State) switchManager
-                                .getNodeConnectorProp(nodeConnector,
-                                        State.StatePropName));
-
-                        String nodeConnectorName = (ncName != null) ? ncName
-                                .getValue() : "";
+                        Config portStatus = ((Config) switchManager.getNodeConnectorProp(nodeConnector,
+                                Config.ConfigPropName));
+                        State portState = ((State) switchManager.getNodeConnectorProp(nodeConnector,
+                                State.StatePropName));
+                        String nodeConnectorName = (ncName != null) ? ncName.getValue() : "";
                         nodeConnectorName += " (" + nodeConnector.getID() + ")";
 
                         if (portStatus != null) {
                             if (portStatus.getValue() == Config.ADMIN_UP) {
                                 if (portState.getValue() == State.EDGE_UP) {
-                                    nodeConnectorName = "<span class='admin-up'>"
-                                            + nodeConnectorName + "</span>";
+                                    nodeConnectorName = "<span class='admin-up'>" + nodeConnectorName + "</span>";
                                 } else if (portState.getValue() == State.EDGE_DOWN) {
-                                    nodeConnectorName = "<span class='edge-down'>"
-                                            + nodeConnectorName + "</span>";
+                                    nodeConnectorName = "<span class='edge-down'>" + nodeConnectorName + "</span>";
                                 }
                             } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
-                                nodeConnectorName = "<span class='admin-down'>"
-                                        + nodeConnectorName + "</span>";
+                                nodeConnectorName = "<span class='admin-down'>" + nodeConnectorName + "</span>";
                             }
                         }
 
                         Class<?> idClass = nodeConnector.getID().getClass();
                         if (idClass.equals(Short.class)) {
-                            portList.put(
-                                    Short.parseShort(nodeConnectorNumberToStr),
-                                    nodeConnectorName);
+                            portList.put(Short.parseShort(nodeConnectorNumberToStr), nodeConnectorName);
                         } else {
                             intfList.add(nodeConnectorName);
                         }
                     }
 
                     if (portList.size() > 0) {
-                        Map<Short, String> sortedPortList = new TreeMap<Short, String>(
-                                portList);
+                        Map<Short, String> sortedPortList = new TreeMap<Short, String>(portList);
 
                         for (Entry<Short, String> e : sortedPortList.entrySet()) {
                             sb1.append(e.getValue());
@@ -210,34 +214,31 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean updateLearntNode(
-            @RequestParam("nodeName") String nodeName,
-            @RequestParam("nodeId") String nodeId,
-            @RequestParam("tier") String tier,
-            @RequestParam("operationMode") String operationMode,
-            HttpServletRequest request,
+    public StatusJsonBean updateLearntNode(@RequestParam("nodeName") String nodeName,
+            @RequestParam("nodeId") String nodeId, @RequestParam("tier") String tier,
+            @RequestParam("operationMode") String operationMode, HttpServletRequest request,
             @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
-        if (DaylightWebUtil
-                .getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
             Map<String, Property> nodeProperties = new HashMap<String, Property>();
             Property desc = new Description(nodeName);
             nodeProperties.put(desc.getName(), desc);
             Property nodeTier = new Tier(Integer.parseInt(tier));
             nodeProperties.put(nodeTier.getName(), nodeTier);
-            Property mode = new ForwardingMode(Integer.parseInt(operationMode));
-            nodeProperties.put(mode.getName(), mode);
+            if (containerName.equals(GlobalConstants.DEFAULT.toString())) {
+                Property mode = new ForwardingMode(Integer.parseInt(operationMode));
+                nodeProperties.put(mode.getName(), mode);
+            }
             SwitchConfig cfg = new SwitchConfig(nodeId, nodeProperties);
             Status result = switchManager.updateNodeConfig(cfg);
             if (!result.isSuccess()) {
@@ -246,36 +247,33 @@ public class Devices implements IDaylightWeb {
             } else {
                 resultBean.setStatus(true);
                 resultBean.setMessage("Updated node information successfully");
+                DaylightWebUtil.auditlog("Property", userName, "updated",
+                        "of Node " + DaylightWebUtil.getNodeDesc(Node.fromString(nodeId), switchManager));
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
-            resultBean.setMessage("Error updating node information. "
-                    + e.getMessage());
+            resultBean.setMessage("Error updating node information. " + e.getMessage());
         }
         return resultBean;
     }
 
     @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 = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        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);
+        IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper.getInstance(
+                IForwardingStaticRouting.class, containerName, this);
         if (staticRouting == null) {
             return null;
         }
         List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
-        ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
-                .getStaticRouteConfigs();
+        ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting.getStaticRouteConfigs();
         if (routeConfigs == null) {
             return null;
         }
@@ -299,27 +297,21 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean addStaticRoute(
-            @RequestParam("routeName") String routeName,
-            @RequestParam("staticRoute") String staticRoute,
-            @RequestParam("nextHop") String nextHop,
-            HttpServletRequest request,
-            @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+    public StatusJsonBean addStaticRoute(@RequestParam("routeName") String routeName,
+            @RequestParam("staticRoute") String staticRoute, @RequestParam("nextHop") String nextHop,
+            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) {
+        if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
             return unauthorizedMessage();
         }
 
         StatusJsonBean result = new StatusJsonBean();
         try {
-            IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
-                    .getInstance(IForwardingStaticRouting.class, containerName,
-                            this);
+            IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper.getInstance(
+                    IForwardingStaticRouting.class, containerName, this);
             StaticRouteConfig config = new StaticRouteConfig();
             config.setName(routeName);
             config.setStaticRoute(staticRoute);
@@ -328,6 +320,7 @@ public class Devices implements IDaylightWeb {
             if (addStaticRouteResult.isSuccess()) {
                 result.setStatus(true);
                 result.setMessage("Static Route saved successfully");
+                DaylightWebUtil.auditlog("Static Route", userName, "added", routeName, containerName);
             } else {
                 result.setStatus(false);
                 result.setMessage(addStaticRouteResult.getDescription());
@@ -341,12 +334,9 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean deleteStaticRoute(
-            @RequestParam("routesToDelete") String routesToDelete,
-            HttpServletRequest request,
-            @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+    public StatusJsonBean deleteStaticRoute(@RequestParam("routesToDelete") String routesToDelete,
+            HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -356,14 +346,12 @@ public class Devices implements IDaylightWeb {
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
-                    .getInstance(IForwardingStaticRouting.class, containerName,
-                            this);
+            IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper.getInstance(
+                    IForwardingStaticRouting.class, containerName, this);
             String[] routes = routesToDelete.split(",");
             Status result;
             resultBean.setStatus(true);
-            resultBean
-                    .setMessage("Successfully deleted selected static routes");
+            resultBean.setMessage("Successfully deleted selected static routes");
             for (String route : routes) {
                 result = staticRouting.removeStaticRoute(route);
                 if (!result.isSuccess()) {
@@ -371,12 +359,11 @@ public class Devices implements IDaylightWeb {
                     resultBean.setMessage(result.getDescription());
                     break;
                 }
+                DaylightWebUtil.auditlog("Static Route", userName, "removed", route, containerName);
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
-            resultBean
-                    .setMessage("Error occurred while deleting static routes. "
-                            + e.getMessage());
+            resultBean.setMessage("Error occurred while deleting static routes. " + e.getMessage());
         }
         return resultBean;
     }
@@ -387,23 +374,35 @@ public class Devices implements IDaylightWeb {
             @RequestParam(required = false) String container) {
         Gson gson = new Gson();
         List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        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);
+        Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
 
         if (privilege != Privilege.NONE) {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, 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));
+                    List<SubnetGatewayPortBean> portsList = new ArrayList<SubnetGatewayPortBean>();
+                    Iterator<NodeConnector> itor = conf.getNodeConnectors().iterator();
+                    while (itor.hasNext()) {
+                        SubnetGatewayPortBean bean = new SubnetGatewayPortBean();
+                        NodeConnector nodeConnector = itor.next();
+                        String nodeName = getNodeDesc(nodeConnector.getNode().toString(), containerName);
+                        Name ncName = ((Name) switchManager.getNodeConnectorProp(nodeConnector, Name.NamePropName));
+                        String nodeConnectorName = (ncName != null) ? ncName.getValue() : "";
+                        bean.setNodeName(nodeName);
+                        bean.setNodePortName(nodeConnectorName);
+                        bean.setNodeId(nodeConnector.getNode().toString());
+                        bean.setNodePortId(nodeConnector.toString());
+                        portsList.add(bean);
+                    }
+                    subnet.put("nodePorts", gson.toJson(portsList));
                     subnets.add(subnet);
                 }
             }
@@ -417,13 +416,10 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean addSubnetGateways(
-            @RequestParam("gatewayName") String gatewayName,
-            @RequestParam("gatewayIPAddress") String gatewayIPAddress,
-            HttpServletRequest request,
+    public StatusJsonBean addSubnetGateways(@RequestParam("gatewayName") String gatewayName,
+            @RequestParam("gatewayIPAddress") String gatewayIPAddress, HttpServletRequest request,
             @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -433,14 +429,14 @@ public class Devices implements IDaylightWeb {
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
-            SubnetConfig cfgObject = new SubnetConfig(gatewayName,
-                    gatewayIPAddress, new ArrayList<String>());
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
+            SubnetConfig cfgObject = new SubnetConfig(gatewayName, gatewayIPAddress, new ArrayList<String>());
             Status result = switchManager.addSubnet(cfgObject);
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
                 resultBean.setMessage("Added gateway address successfully");
+                DaylightWebUtil.auditlog("Subnet Gateway", userName, "added", gatewayName, containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -454,12 +450,9 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean deleteSubnetGateways(
-            @RequestParam("gatewaysToDelete") String gatewaysToDelete,
-            HttpServletRequest request,
-            @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+    public StatusJsonBean deleteSubnetGateways(@RequestParam("gatewaysToDelete") String gatewaysToDelete,
+            HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -469,8 +462,8 @@ public class Devices implements IDaylightWeb {
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
             String[] subnets = gatewaysToDelete.split(",");
             resultBean.setStatus(true);
             resultBean.setMessage("Added gateway address successfully");
@@ -481,6 +474,7 @@ public class Devices implements IDaylightWeb {
                     resultBean.setMessage(result.getDescription());
                     break;
                 }
+                DaylightWebUtil.auditlog("Subnet Gateway", userName, "removed", subnet, containerName);
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
@@ -491,13 +485,10 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean addSubnetGatewayPort(
-            @RequestParam("portsName") String portsName,
-            @RequestParam("ports") String ports,
-            @RequestParam("nodeId") String nodeId, HttpServletRequest request,
+    public StatusJsonBean addSubnetGatewayPort(@RequestParam("portsName") String portsName,
+            @RequestParam("ports") String ports, @RequestParam("nodeId") String nodeId, HttpServletRequest request,
             @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -507,15 +498,22 @@ public class Devices implements IDaylightWeb {
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
-            Status result = switchManager.addPortsToSubnet(portsName, nodeId
-                    + "/" + ports);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
+            List<String> toAdd = new ArrayList<String>();
+            for (String port : ports.split(",")) {
+                toAdd.add(port);
+            }
+            Status result = switchManager.addPortsToSubnet(portsName, toAdd);
 
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
-                resultBean
-                        .setMessage("Added ports to subnet gateway address successfully");
+                resultBean.setMessage("Added ports to subnet gateway address successfully");
+                for (String port : toAdd) {
+                    DaylightWebUtil.auditlog("Port", userName, "added",
+                            DaylightWebUtil.getPortName(NodeConnector.fromString(port), switchManager)
+                            + " to Subnet Gateway " + portsName, containerName);
+                }
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -529,13 +527,10 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean deleteSubnetGatewayPort(
-            @RequestParam("gatewayName") String gatewayName,
-            @RequestParam("nodePort") String nodePort,
-            HttpServletRequest request,
+    public StatusJsonBean deleteSubnetGatewayPort(@RequestParam("gatewayName") String gatewayName,
+            @RequestParam("nodePort") String nodePort, HttpServletRequest request,
             @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -545,15 +540,22 @@ public class Devices implements IDaylightWeb {
 
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
-            Status result = switchManager.removePortsFromSubnet(gatewayName,
-                    nodePort);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
+            List<String> toRemove = new ArrayList<String>();
+            for (String port : nodePort.split(",")) {
+                toRemove.add(port);
+            }
+            Status result = switchManager.removePortsFromSubnet(gatewayName, toRemove);
 
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
-                resultBean
-                        .setMessage("Deleted port from subnet gateway address successfully");
+                resultBean.setMessage("Deleted port from subnet gateway address successfully");
+                for (String port : toRemove) {
+                    DaylightWebUtil.auditlog("Port", userName, "removed",
+                            DaylightWebUtil.getPortName(NodeConnector.fromString(port), switchManager)
+                            + " from Subnet Gateway " + gatewayName, containerName);
+                }
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
@@ -567,22 +569,19 @@ 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<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        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);
+        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);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
             if (switchManager != null) {
                 for (SpanConfig conf : switchManager.getSpanConfigList()) {
                     spanConfigs_json.add(gson.toJson(conf));
@@ -593,14 +592,17 @@ public class Devices implements IDaylightWeb {
             for (String config_json : spanConfigs_json) {
                 try {
                     @SuppressWarnings("unchecked")
-                    Map<String, String> config_data = mapper.readValue(config_json,
-                            HashMap.class);
+                    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));
+                        // Add switch portName value (non-configuration field)
+                        config.put("nodeName", getNodeDesc(config_data.get("nodeId"), containerName));
+                        NodeConnector spanPortNodeConnector = NodeConnector.fromString(config_data.get("spanPort"));
+                        Name ncName = ((Name) switchManager.getNodeConnectorProp(spanPortNodeConnector,
+                                Name.NamePropName));
+                        String spanPortName = (ncName != null) ? ncName.getValue() : "";
+                        config.put("spanPortName", spanPortName);
                     }
                     config.put("json", config_json);
                     spanConfigs.add(config);
@@ -619,10 +621,8 @@ public class Devices implements IDaylightWeb {
 
     @RequestMapping(value = "/nodeports")
     @ResponseBody
-    public Map<String, Object> getNodePorts(HttpServletRequest request,
-            @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+    public String 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();
@@ -630,44 +630,39 @@ public class Devices implements IDaylightWeb {
             return null;
         }
 
-
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
         if (switchManager == null) {
             return null;
         }
-
-        Map<String, Object> nodes = new HashMap<String, Object>();
-        Map<Short, String> port;
+        List<NodeJsonBean> nodeJsonBeans = new ArrayList<NodeJsonBean>();
 
         for (Switch node : switchManager.getNetworkDevices()) {
-            port = new HashMap<Short, String>(); // new port
+            NodeJsonBean nodeJsonBean = new NodeJsonBean();
+            List<PortJsonBean> port = new ArrayList<PortJsonBean>();
             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
-
             if (nodeConnectorSet != null) {
                 for (NodeConnector nodeConnector : nodeConnectorSet) {
-                    String nodeConnectorName = ((Name) switchManager
-                            .getNodeConnectorProp(nodeConnector,
-                                    Name.NamePropName)).getValue();
-                    port.put((Short) nodeConnector.getID(), nodeConnectorName
-                            + "(" + nodeConnector.getID() + ")");
+                    String nodeConnectorName = ((Name) switchManager.getNodeConnectorProp(nodeConnector,
+                            Name.NamePropName)).getValue();
+                    port.add(new PortJsonBean(nodeConnector.getID().toString(), nodeConnectorName, nodeConnector
+                            .toString()));
                 }
             }
-
-            nodes.put(node.getNode().toString(), port);
+            nodeJsonBean.setNodeId(node.getNode().toString());
+            nodeJsonBean.setNodeName(getNodeDesc(node.getNode().toString(), containerName));
+            nodeJsonBean.setNodePorts(port);
+            nodeJsonBeans.add(nodeJsonBean);
         }
 
-        return nodes;
+        return new Gson().toJson(nodeJsonBeans);
     }
 
     @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean addSpanPort(
-            @RequestParam("jsonData") String jsonData,
-            HttpServletRequest request,
+    public StatusJsonBean addSpanPort(@RequestParam("jsonData") String jsonData, HttpServletRequest request,
             @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -678,33 +673,32 @@ public class Devices implements IDaylightWeb {
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
             Gson gson = new Gson();
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
             SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
             Status result = switchManager.addSpanConfig(cfgObject);
             if (result.isSuccess()) {
                 resultBean.setStatus(true);
                 resultBean.setMessage("SPAN Port added successfully");
+                DaylightWebUtil.auditlog("SPAN Port", userName, "added",
+                        DaylightWebUtil.getPortName(NodeConnector.fromString(cfgObject.getSpanPort()), switchManager),
+                        containerName);
             } else {
                 resultBean.setStatus(false);
                 resultBean.setMessage(result.getDescription());
             }
         } catch (Exception e) {
             resultBean.setStatus(false);
-            resultBean.setMessage("Error occurred while adding span port. "
-                    + e.getMessage());
+            resultBean.setMessage("Error occurred while adding span port. " + e.getMessage());
         }
         return resultBean;
     }
 
     @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
     @ResponseBody
-    public StatusJsonBean deleteSpanPorts(
-            @RequestParam("spanPortsToDelete") String spanPortsToDelete,
-            HttpServletRequest request,
-            @RequestParam(required = false) String container) {
-        String containerName = (container == null) ? GlobalConstants.DEFAULT
-                .toString() : container;
+    public StatusJsonBean deleteSpanPorts(@RequestParam("spanPortsToDelete") String spanPortsToDelete,
+            HttpServletRequest request, @RequestParam(required = false) String container) {
+        String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
 
         // Authorization check
         String userName = request.getUserPrincipal().getName();
@@ -715,43 +709,132 @@ public class Devices implements IDaylightWeb {
         StatusJsonBean resultBean = new StatusJsonBean();
         try {
             Gson gson = new Gson();
-            ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                    .getInstance(ISwitchManager.class, containerName, this);
-            String[] spans = spanPortsToDelete.split("###");
-            resultBean.setStatus(true);
-            resultBean.setMessage("SPAN Port(s) deleted successfully");
-            for (String span : spans) {
-                if (!span.isEmpty()) {
-                    SpanConfig cfgObject = gson
-                            .fromJson(span, SpanConfig.class);
-                    Status result = switchManager.removeSpanConfig(cfgObject);
-                    if (!result.isSuccess()) {
-                        resultBean.setStatus(false);
-                        resultBean.setMessage(result.getDescription());
-                        break;
-                    }
+            ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                    containerName, this);
+            Type collectionType = new TypeToken<List<SpanPortJsonBean>>() {
+            }.getType();
+            List<SpanPortJsonBean> jsonBeanList = gson.fromJson(spanPortsToDelete, collectionType);
+            for (SpanPortJsonBean jsonBean : jsonBeanList) {
+                SpanConfig cfgObject = gson.fromJson(gson.toJson(jsonBean), SpanConfig.class);
+                Status result = switchManager.removeSpanConfig(cfgObject);
+                if (!result.isSuccess()) {
+                    resultBean.setStatus(false);
+                    resultBean.setMessage(result.getDescription());
+                    break;
                 }
+                DaylightWebUtil.auditlog("SPAN Port", userName, "removed",
+                        DaylightWebUtil.getPortName(NodeConnector.fromString(cfgObject.getSpanPort()), switchManager),
+                        containerName);
             }
+            resultBean.setStatus(true);
+            resultBean.setMessage("SPAN Port(s) deleted successfully");
         } catch (Exception e) {
             resultBean.setStatus(false);
-            resultBean.setMessage("Error occurred while deleting span port. "
-                    + e.getMessage());
+            resultBean.setMessage("Error occurred while deleting span port. " + e.getMessage());
         }
         return resultBean;
     }
 
+    @RequestMapping(value = "/connect/nodes", method = RequestMethod.GET)
+    @ResponseBody
+    public List<NodeJsonBean> getNodes(HttpServletRequest request) {
+        IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+                IConnectionManager.class, this);
+        if (connectionManager == null) {
+            return null;
+        }
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class,
+                GlobalConstants.DEFAULT.toString(), this);
+        if (switchManager == null) {
+            return null;
+        }
+
+        Set<Node> nodes = connectionManager.getLocalNodes();
+        List<NodeJsonBean> result = new LinkedList<NodeJsonBean>();
+        for (Node node : nodes) {
+            Description descriptionProperty = (Description) switchManager.getNodeProp(node, "description");
+            String description = descriptionProperty.getValue();
+            NodeJsonBean nodeBean = new NodeJsonBean();
+            nodeBean.setNodeId(node.getNodeIDString());
+            nodeBean.setNodeType(node.getType());
+            if (description.equals("None")) {
+                nodeBean.setNodeName(node.toString());
+            } else {
+                nodeBean.setNodeName(description);
+            }
+            result.add(nodeBean);
+        }
+
+        return result;
+    }
+
+    @RequestMapping(value = "/connect/{nodeId}", method = RequestMethod.POST)
+    @ResponseBody
+    public Status addNode(HttpServletRequest request, @PathVariable("nodeId") String nodeId,
+            @RequestParam(required = true) String ipAddress, @RequestParam(required = true) String port,
+            @RequestParam(required = false) String nodeType) {
+        IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+                IConnectionManager.class, this);
+        if (connectionManager == null) {
+            return new Status(StatusCode.NOTFOUND, "Service not found");
+        }
+
+        if (!NetUtils.isIPv4AddressValid(ipAddress)) {
+            return new Status(StatusCode.NOTACCEPTABLE, "Invalid IP Address: " + ipAddress);
+        }
+
+        try {
+            Integer.parseInt(port);
+        } catch (Exception e) {
+            return new Status(StatusCode.NOTACCEPTABLE, "Invalid Layer 4 Port: " + port);
+        }
+
+        Map<ConnectionConstants, String> params = new HashMap<ConnectionConstants, String>();
+        params.put(ConnectionConstants.ADDRESS, ipAddress);
+        params.put(ConnectionConstants.PORT, port);
+
+        Node node = null;
+        if (nodeType != null) {
+            node = connectionManager.connect(nodeType, nodeId, params);
+        } else {
+            node = connectionManager.connect(nodeId, params);
+        }
+        if (node == null) {
+            return new Status(StatusCode.NOTFOUND, "Failed to connect to Node at " + ipAddress + ":" + port);
+        }
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    @RequestMapping(value = "/disconnect/{nodeId}", method = RequestMethod.POST)
+    @ResponseBody
+    public Status removeNode(HttpServletRequest request, @PathVariable("nodeId") String nodeId,
+            @RequestParam(required = true) String nodeType) {
+        IConnectionManager connectionManager = (IConnectionManager) ServiceHelper.getGlobalInstance(
+                IConnectionManager.class, this);
+        if (connectionManager == null) {
+            return new Status(StatusCode.NOTFOUND, "Service not found");
+        }
+
+        try {
+            Node node = new Node(nodeType, nodeId);
+            return connectionManager.disconnect(node);
+        } catch (Exception e) {
+            return new Status(StatusCode.NOTFOUND, "Resource not found");
+        }
+    }
+
     private String getNodeDesc(String nodeId, String containerName) {
-        ISwitchManager switchManager = (ISwitchManager) ServiceHelper
-                .getInstance(ISwitchManager.class, containerName, this);
+        ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
+                this);
         String description = "";
         if (switchManager != null) {
-            Description desc = (Description) switchManager.getNodeProp(Node.fromString(nodeId), Description.propertyName);
-            if(desc != null) {
+            Description desc = (Description) switchManager.getNodeProp(Node.fromString(nodeId),
+                    Description.propertyName);
+            if (desc != null) {
                 description = desc.getValue();
             }
         }
-        return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
-                : description;
+        return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId : description;
     }
 
     private StatusJsonBean unauthorizedMessage() {
@@ -762,9 +845,7 @@ public class Devices implements IDaylightWeb {
     }
 
     @RequestMapping(value = "login")
-    public String login(final HttpServletRequest request,
-            final HttpServletResponse response) {
-        // response.setHeader("X-Page-Location", "/login");
+    public String login(final HttpServletRequest request, final HttpServletResponse response) {
         /*
          * IUserManager userManager = (IUserManager) ServiceHelper
          * .getGlobalInstance(IUserManager.class, this); if (userManager ==
@@ -779,4 +860,4 @@ public class Devices implements IDaylightWeb {
         return "forward:" + "/";
     }
 
-}
+}
\ No newline at end of file