2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.devices.web;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
15 import java.util.Map.Entry;
17 import java.util.TreeMap;
18 import java.util.concurrent.ConcurrentMap;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
22 import org.codehaus.jackson.map.ObjectMapper;
23 import org.opendaylight.controller.usermanager.IUserManager;
24 import org.opendaylight.controller.web.DaylightWebUtil;
25 import org.opendaylight.controller.web.IDaylightWeb;
26 import org.springframework.stereotype.Controller;
27 import org.springframework.web.bind.annotation.RequestMapping;
28 import org.springframework.web.bind.annotation.RequestMethod;
29 import org.springframework.web.bind.annotation.RequestParam;
30 import org.springframework.web.bind.annotation.ResponseBody;
31 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
32 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
33 import org.opendaylight.controller.sal.authorization.UserLevel;
34 import org.opendaylight.controller.sal.core.Config;
35 import org.opendaylight.controller.sal.core.Name;
36 import org.opendaylight.controller.sal.core.Node;
37 import org.opendaylight.controller.sal.core.NodeConnector;
38 import org.opendaylight.controller.sal.core.Tier;
39 import org.opendaylight.controller.sal.utils.HexEncode;
40 import org.opendaylight.controller.sal.utils.ServiceHelper;
41 import org.opendaylight.controller.sal.utils.Status;
42 import org.opendaylight.controller.sal.utils.TierHelper;
43 import org.opendaylight.controller.switchmanager.ISwitchManager;
44 import org.opendaylight.controller.switchmanager.SpanConfig;
45 import org.opendaylight.controller.switchmanager.SubnetConfig;
46 import org.opendaylight.controller.switchmanager.Switch;
47 import org.opendaylight.controller.switchmanager.SwitchConfig;
49 import com.google.gson.Gson;
53 public class Devices implements IDaylightWeb {
54 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
55 private final String WEB_NAME = "Devices";
56 private final String WEB_ID = "devices";
57 private final short WEB_ORDER = 1;
60 ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
64 public String getWebName() {
69 public String getWebId() {
74 public short getWebOrder() {
79 public boolean isAuthorized(UserLevel userLevel) {
80 return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
83 @RequestMapping(value = "/nodesLearnt", method = RequestMethod.GET)
85 public DevicesJsonBean getNodesLearnt(HttpServletRequest request, @RequestParam(required = false) String container) {
86 Gson gson = new Gson();
87 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
88 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
89 .getInstance(ISwitchManager.class, containerName, this);
90 List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
91 if (switchManager != null) {
92 for (Switch device : switchManager.getNetworkDevices()) {
93 HashMap<String, String> nodeDatum = new HashMap<String, String>();
94 Node node = device.getNode();
95 Tier tier = (Tier) switchManager.getNodeProp(node,
98 nodeDatum.put("containerName", containerName);
99 nodeDatum.put("nodeName",
100 switchManager.getNodeDescription(node));
101 nodeDatum.put("nodeId", node.toString());
102 int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
104 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
105 + " (Tier-" + tierNumber + ")");
106 nodeDatum.put("tier", tierNumber + "");
107 SwitchConfig sc = switchManager.getSwitchConfig(device
108 .getNode().toString());
109 String modeStr = (sc != null) ? sc.getMode() : "0";
110 nodeDatum.put("mode", modeStr);
112 nodeDatum.put("json", gson.toJson(nodeDatum));
113 nodeDatum.put("mac", HexEncode.bytesToHexString(device
114 .getDataLayerAddress()));
115 StringBuffer sb1 = new StringBuffer();
116 Set<NodeConnector> nodeConnectorSet = device
117 .getNodeConnectors();
118 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
119 Map<Short, String> portList = new HashMap<Short, String>();
120 List<String> intfList = new ArrayList<String>();
121 for (NodeConnector nodeConnector : nodeConnectorSet) {
122 String nodeConnectorNumberToStr = nodeConnector.getID()
124 Name ncName = ((Name) switchManager
125 .getNodeConnectorProp(nodeConnector,
127 Config portStatus = ((Config) switchManager
128 .getNodeConnectorProp(nodeConnector,
129 Config.ConfigPropName));
131 String nodeConnectorName = (ncName != null) ? ncName
133 nodeConnectorName += " (" + nodeConnector.getID() + ")";
135 if (portStatus != null) {
136 if (portStatus.getValue() == Config.ADMIN_UP) {
137 nodeConnectorName = "<span style='color:green;'>"
138 + nodeConnectorName + "</span>";
139 } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
140 nodeConnectorName = "<span style='color:red;'>"
141 + nodeConnectorName + "</span>";
145 Class<?> idClass = nodeConnector.getID().getClass();
146 if (idClass.equals(Short.class)) {
148 Short.parseShort(nodeConnectorNumberToStr),
151 intfList.add(nodeConnectorName);
155 if (portList.size() > 0) {
156 Map<Short, String> sortedPortList = new TreeMap<Short, String>(
159 for (Entry<Short, String> e : sortedPortList.entrySet()) {
160 sb1.append(e.getValue());
163 } else if (intfList.size() > 0) {
164 for (String intf : intfList) {
170 nodeDatum.put("ports", sb1.toString());
171 nodeData.add(nodeDatum);
175 DevicesJsonBean result = new DevicesJsonBean();
176 result.setNodeData(nodeData);
177 List<String> columnNames = new ArrayList<String>();
178 columnNames.add("Node ID");
179 columnNames.add("Node Name");
180 columnNames.add("Tier");
181 columnNames.add("Mac Address");
182 columnNames.add("Ports");
183 columnNames.add("Port Status");
185 result.setColumnNames(columnNames);
189 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
191 public List<String> getTiers() {
192 return TierHelper.getTiers();
195 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
197 public StatusJsonBean updateLearntNode(
198 @RequestParam("nodeName") String nodeName,
199 @RequestParam("nodeId") String nodeId,
200 @RequestParam("tier") String tier,
201 @RequestParam("operationMode") String operationMode,
202 HttpServletRequest request, @RequestParam(required = false) String container) {
203 if (!authorize(UserLevel.NETWORKADMIN, request)) {
204 return unauthorizedMessage();
207 StatusJsonBean resultBean = new StatusJsonBean();
208 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
210 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
211 .getInstance(ISwitchManager.class, containerName, this);
212 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
214 switchManager.updateSwitchConfig(cfg);
215 resultBean.setStatus(true);
216 resultBean.setMessage("Updated node information successfully");
217 } catch (Exception e) {
218 resultBean.setStatus(false);
219 resultBean.setMessage("Error updating node information. "
225 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
227 public DevicesJsonBean getStaticRoutes(HttpServletRequest request, @RequestParam(required = false) String container) {
228 Gson gson = new Gson();
229 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
230 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
231 .getInstance(IForwardingStaticRouting.class, containerName,
233 if (staticRouting == null) {
236 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
237 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
238 .getStaticRouteConfigs();
239 if (routeConfigs == null) {
242 for (StaticRouteConfig conf : routeConfigs.values()) {
243 Map<String, String> staticRoute = new HashMap<String, String>();
244 staticRoute.put("name", conf.getName());
245 staticRoute.put("staticRoute", conf.getStaticRoute());
246 staticRoute.put("nextHopType", conf.getNextHopType());
247 staticRoute.put("nextHop", conf.getNextHop());
248 staticRoute.put("json", gson.toJson(conf));
249 staticRoutes.add(staticRoute);
251 DevicesJsonBean result = new DevicesJsonBean();
252 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
253 result.setNodeData(staticRoutes);
257 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
259 public StatusJsonBean addStaticRoute(
260 @RequestParam("routeName") String routeName,
261 @RequestParam("staticRoute") String staticRoute,
262 @RequestParam("nextHop") String nextHop,
263 HttpServletRequest request, @RequestParam(required = false) String container) {
264 if (!authorize(UserLevel.NETWORKADMIN, request)) {
265 return unauthorizedMessage();
268 StatusJsonBean result = new StatusJsonBean();
269 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
271 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
272 .getInstance(IForwardingStaticRouting.class, containerName,
274 StaticRouteConfig config = new StaticRouteConfig();
275 config.setName(routeName);
276 config.setStaticRoute(staticRoute);
277 config.setNextHop(nextHop);
278 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
279 if (addStaticRouteResult.isSuccess()) {
280 result.setStatus(true);
281 result.setMessage("Static Route saved successfully");
283 result.setStatus(false);
284 result.setMessage(addStaticRouteResult.getDescription());
286 } catch (Exception e) {
287 result.setStatus(false);
288 result.setMessage("Error - " + e.getMessage());
293 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
295 public StatusJsonBean deleteStaticRoute(
296 @RequestParam("routesToDelete") String routesToDelete,
297 HttpServletRequest request, @RequestParam(required = false) String container) {
298 if (!authorize(UserLevel.NETWORKADMIN, request)) {
299 return unauthorizedMessage();
302 StatusJsonBean resultBean = new StatusJsonBean();
303 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
305 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
306 .getInstance(IForwardingStaticRouting.class, containerName,
308 String[] routes = routesToDelete.split(",");
310 resultBean.setStatus(true);
312 .setMessage("Successfully deleted selected static routes");
313 for (String route : routes) {
314 result = staticRouting.removeStaticRoute(route);
315 if (!result.isSuccess()) {
316 resultBean.setStatus(false);
317 resultBean.setMessage(result.getDescription());
321 } catch (Exception e) {
322 resultBean.setStatus(false);
324 .setMessage("Error occurred while deleting static routes. "
330 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
332 public DevicesJsonBean getSubnetGateways(HttpServletRequest request, @RequestParam(required = false) String container) {
333 Gson gson = new Gson();
334 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
335 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
336 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
337 .getInstance(ISwitchManager.class, containerName, this);
338 if (switchManager != null) {
339 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
340 Map<String, String> subnet = new HashMap<String, String>();
341 subnet.put("name", conf.getName());
342 subnet.put("subnet", conf.getSubnet());
343 subnet.put("json", gson.toJson(conf));
347 DevicesJsonBean result = new DevicesJsonBean();
348 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
349 result.setNodeData(subnets);
353 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
355 public StatusJsonBean addSubnetGateways(
356 @RequestParam("gatewayName") String gatewayName,
357 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
358 HttpServletRequest request, @RequestParam(required = false) String container) {
359 if (!authorize(UserLevel.NETWORKADMIN, request)) {
360 return unauthorizedMessage();
363 StatusJsonBean resultBean = new StatusJsonBean();
364 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
366 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
367 .getInstance(ISwitchManager.class, containerName, this);
368 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
369 gatewayIPAddress, new ArrayList<String>());
370 Status result = switchManager.addSubnet(cfgObject);
371 if (result.isSuccess()) {
372 resultBean.setStatus(true);
373 resultBean.setMessage("Added gateway address successfully");
375 resultBean.setStatus(false);
376 resultBean.setMessage(result.getDescription());
378 } catch (Exception e) {
379 resultBean.setStatus(false);
380 resultBean.setMessage(e.getMessage());
385 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
387 public StatusJsonBean deleteSubnetGateways(
388 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
389 HttpServletRequest request, @RequestParam(required = false) String container) {
390 if (!authorize(UserLevel.NETWORKADMIN, request)) {
391 return unauthorizedMessage();
394 StatusJsonBean resultBean = new StatusJsonBean();
395 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
397 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
398 .getInstance(ISwitchManager.class, containerName, this);
399 String[] subnets = gatewaysToDelete.split(",");
400 resultBean.setStatus(true);
401 resultBean.setMessage("Added gateway address successfully");
402 for (String subnet : subnets) {
403 Status result = switchManager.removeSubnet(subnet);
404 if (!result.isSuccess()) {
405 resultBean.setStatus(false);
406 resultBean.setMessage(result.getDescription());
410 } catch (Exception e) {
411 resultBean.setStatus(false);
412 resultBean.setMessage(e.getMessage());
417 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
419 public StatusJsonBean addSubnetGatewayPort(
420 @RequestParam("portsName") String portsName,
421 @RequestParam("ports") String ports,
422 @RequestParam("nodeId") String nodeId,
423 HttpServletRequest request, @RequestParam(required = false) String container) {
424 if (!authorize(UserLevel.NETWORKADMIN, request)) {
425 return unauthorizedMessage();
428 StatusJsonBean resultBean = new StatusJsonBean();
429 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
431 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
432 .getInstance(ISwitchManager.class, containerName, this);
433 Status result = switchManager.addPortsToSubnet(portsName, nodeId
436 if (result.isSuccess()) {
437 resultBean.setStatus(true);
439 .setMessage("Added ports to subnet gateway address successfully");
441 resultBean.setStatus(false);
442 resultBean.setMessage(result.getDescription());
444 } catch (Exception e) {
445 resultBean.setStatus(false);
446 resultBean.setMessage(e.getMessage());
451 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
453 public StatusJsonBean deleteSubnetGatewayPort(
454 @RequestParam("gatewayName") String gatewayName,
455 @RequestParam("nodePort") String nodePort,
456 HttpServletRequest request, @RequestParam(required = false) String container) {
457 if (!authorize(UserLevel.NETWORKADMIN, request)) {
458 return unauthorizedMessage();
461 StatusJsonBean resultBean = new StatusJsonBean();
462 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
464 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
465 .getInstance(ISwitchManager.class, containerName, this);
466 Status result = switchManager.removePortsFromSubnet(gatewayName,
469 if (result.isSuccess()) {
470 resultBean.setStatus(true);
472 .setMessage("Deleted port from subnet gateway address successfully");
474 resultBean.setStatus(false);
475 resultBean.setMessage(result.getDescription());
477 } catch (Exception e) {
478 resultBean.setStatus(false);
479 resultBean.setMessage(e.getMessage());
484 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
486 public DevicesJsonBean getSpanPorts(HttpServletRequest request, @RequestParam(required = false) String container) {
487 Gson gson = new Gson();
488 List<String> spanConfigs_json = new ArrayList<String>();
489 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
490 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
491 .getInstance(ISwitchManager.class, containerName, this);
492 if (switchManager != null) {
493 for (SpanConfig conf : switchManager.getSpanConfigList()) {
494 spanConfigs_json.add(gson.toJson(conf));
497 ObjectMapper mapper = new ObjectMapper();
498 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
499 for (String config_json : spanConfigs_json) {
501 @SuppressWarnings("unchecked")
502 Map<String, String> config_data = mapper.readValue(config_json,
504 Map<String, String> config = new HashMap<String, String>();
505 for (String name : config_data.keySet()) {
506 config.put(name, config_data.get(name));
507 // Add switch name value (non-configuration field)
508 config.put("nodeName",
509 getNodeDesc(config_data.get("nodeId"), containerName));
511 config.put("json", config_json);
512 spanConfigs.add(config);
513 } catch (Exception e) {
514 // TODO: Handle the exception.
517 DevicesJsonBean result = new DevicesJsonBean();
518 result.setColumnNames(SpanConfig.getGuiFieldsNames());
519 result.setNodeData(spanConfigs);
523 @RequestMapping(value = "/nodeports")
525 public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
526 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
527 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
528 .getInstance(ISwitchManager.class, containerName, this);
529 if (switchManager == null) {
533 Map<String, Object> nodes = new HashMap<String, Object>();
534 Map<Short, String> port;
536 for (Switch node : switchManager.getNetworkDevices()) {
537 port = new HashMap<Short, String>(); // new port
538 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
540 if (nodeConnectorSet != null)
541 for (NodeConnector nodeConnector : nodeConnectorSet) {
542 String nodeConnectorName = ((Name) switchManager
543 .getNodeConnectorProp(nodeConnector,
544 Name.NamePropName)).getValue();
545 port.put((Short) nodeConnector.getID(), nodeConnectorName
546 + "(" + nodeConnector.getID() + ")");
549 nodes.put(node.getNode().toString(), port);
555 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
557 public StatusJsonBean addSpanPort(
558 @RequestParam("jsonData") String jsonData,
559 HttpServletRequest request, @RequestParam(required = false) String container) {
560 if (!authorize(UserLevel.NETWORKADMIN, request)) {
561 return unauthorizedMessage();
564 StatusJsonBean resultBean = new StatusJsonBean();
566 Gson gson = new Gson();
567 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
568 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
569 .getInstance(ISwitchManager.class, containerName, this);
570 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
571 Status result = switchManager.addSpanConfig(cfgObject);
572 if (result.isSuccess()) {
573 resultBean.setStatus(true);
574 resultBean.setMessage("SPAN Port added successfully");
576 resultBean.setStatus(false);
577 resultBean.setMessage(result.getDescription());
579 } catch (Exception e) {
580 resultBean.setStatus(false);
581 resultBean.setMessage("Error occurred while adding span port. "
587 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
589 public StatusJsonBean deleteSpanPorts(
590 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
591 HttpServletRequest request, @RequestParam(required = false) String container) {
592 if (!authorize(UserLevel.NETWORKADMIN, request)) {
593 return unauthorizedMessage();
596 StatusJsonBean resultBean = new StatusJsonBean();
598 Gson gson = new Gson();
599 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
600 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
601 .getInstance(ISwitchManager.class, containerName, this);
602 String[] spans = spanPortsToDelete.split("###");
603 resultBean.setStatus(true);
604 resultBean.setMessage("SPAN Port(s) deleted successfully");
605 for (String span : spans) {
606 if (!span.isEmpty()) {
607 SpanConfig cfgObject = gson
608 .fromJson(span, SpanConfig.class);
609 Status result = switchManager.removeSpanConfig(cfgObject);
610 if (!result.isSuccess()) {
611 resultBean.setStatus(false);
612 resultBean.setMessage(result.getDescription());
617 } catch (Exception e) {
618 resultBean.setStatus(false);
619 resultBean.setMessage("Error occurred while deleting span port. "
625 private String getNodeDesc(String nodeId, String containerName) {
626 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
627 .getInstance(ISwitchManager.class, containerName, this);
628 String description = "";
629 if (switchManager != null) {
630 description = switchManager.getNodeDescription(Node
631 .fromString(nodeId));
633 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
638 * Is the operation permitted for the given level
642 private boolean authorize(UserLevel level, HttpServletRequest request) {
643 IUserManager userManager = (IUserManager) ServiceHelper
644 .getGlobalInstance(IUserManager.class, this);
645 if (userManager == null) {
649 String username = request.getUserPrincipal().getName();
650 UserLevel userLevel = userManager.getUserLevel(username);
651 if (userLevel.toNumber() <= level.toNumber()) {
657 private StatusJsonBean unauthorizedMessage() {
658 StatusJsonBean message = new StatusJsonBean();
659 message.setStatus(false);
660 message.setMessage("Operation not authorized");
664 @RequestMapping(value = "login")
665 public String login(final HttpServletRequest request,
666 final HttpServletResponse response) {
667 // response.setHeader("X-Page-Location", "/login");
669 * IUserManager userManager = (IUserManager) ServiceHelper
670 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
671 * null) { return "User Manager is not available"; }
673 * String username = request.getUserPrincipal().getName();
676 * model.addAttribute("username", username); model.addAttribute("role",
677 * userManager.getUserLevel(username).toNumber());
679 return "forward:" + "/";