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.GlobalConstants;
40 import org.opendaylight.controller.sal.utils.HexEncode;
41 import org.opendaylight.controller.sal.utils.ServiceHelper;
42 import org.opendaylight.controller.sal.utils.Status;
43 import org.opendaylight.controller.sal.utils.TierHelper;
44 import org.opendaylight.controller.switchmanager.ISwitchManager;
45 import org.opendaylight.controller.switchmanager.SpanConfig;
46 import org.opendaylight.controller.switchmanager.SubnetConfig;
47 import org.opendaylight.controller.switchmanager.Switch;
48 import org.opendaylight.controller.switchmanager.SwitchConfig;
50 import com.google.gson.Gson;
54 public class Devices implements IDaylightWeb {
55 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
56 private final String WEB_NAME = "Devices";
57 private final String WEB_ID = "devices";
58 private final short WEB_ORDER = 1;
61 ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
65 public String getWebName() {
70 public String getWebId() {
75 public short getWebOrder() {
80 public boolean isAuthorized(UserLevel userLevel) {
81 return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
84 @RequestMapping(value = "/nodesLearnt", method = RequestMethod.GET)
86 public DevicesJsonBean getNodesLearnt(HttpServletRequest request, @RequestParam(required = false) String container) {
87 Gson gson = new Gson();
88 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
89 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
90 .getInstance(ISwitchManager.class, containerName, this);
91 List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
92 if (switchManager != null) {
93 for (Switch device : switchManager.getNetworkDevices()) {
94 HashMap<String, String> nodeDatum = new HashMap<String, String>();
95 Node node = device.getNode();
96 Tier tier = (Tier) switchManager.getNodeProp(node,
99 nodeDatum.put("containerName", containerName);
100 nodeDatum.put("nodeName",
101 switchManager.getNodeDescription(node));
102 nodeDatum.put("nodeId", node.toString());
103 int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
105 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
106 + " (Tier-" + tierNumber + ")");
107 nodeDatum.put("tier", tierNumber + "");
108 SwitchConfig sc = switchManager.getSwitchConfig(device
109 .getNode().toString());
110 String modeStr = (sc != null) ? sc.getMode() : "0";
111 nodeDatum.put("mode", modeStr);
113 nodeDatum.put("json", gson.toJson(nodeDatum));
114 nodeDatum.put("mac", HexEncode.bytesToHexString(device
115 .getDataLayerAddress()));
116 StringBuffer sb1 = new StringBuffer();
117 Set<NodeConnector> nodeConnectorSet = device
118 .getNodeConnectors();
119 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
120 Map<Short, String> portList = new HashMap<Short, 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>";
146 Short.parseShort(nodeConnectorNumberToStr),
150 Map<Short, String> sortedPortList = new TreeMap<Short, String>(
153 for (Entry<Short, String> e : sortedPortList.entrySet()) {
154 sb1.append(e.getValue());
158 nodeDatum.put("ports", sb1.toString());
159 nodeData.add(nodeDatum);
163 DevicesJsonBean result = new DevicesJsonBean();
164 result.setNodeData(nodeData);
165 List<String> columnNames = new ArrayList<String>();
166 columnNames.add("Node ID");
167 columnNames.add("Node Name");
168 columnNames.add("Tier");
169 columnNames.add("Mac Address");
170 columnNames.add("Ports");
171 columnNames.add("Port Status");
173 result.setColumnNames(columnNames);
177 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
179 public List<String> getTiers() {
180 return TierHelper.getTiers();
183 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
185 public StatusJsonBean updateLearntNode(
186 @RequestParam("nodeName") String nodeName,
187 @RequestParam("nodeId") String nodeId,
188 @RequestParam("tier") String tier,
189 @RequestParam("operationMode") String operationMode,
190 HttpServletRequest request, @RequestParam(required = false) String container) {
191 if (!authorize(UserLevel.NETWORKADMIN, request)) {
192 return unauthorizedMessage();
195 StatusJsonBean resultBean = new StatusJsonBean();
196 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
198 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
199 .getInstance(ISwitchManager.class, containerName, this);
200 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
202 switchManager.updateSwitchConfig(cfg);
203 resultBean.setStatus(true);
204 resultBean.setMessage("Updated node information successfully");
205 } catch (Exception e) {
206 resultBean.setStatus(false);
207 resultBean.setMessage("Error updating node information. "
213 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
215 public DevicesJsonBean getStaticRoutes(HttpServletRequest request, @RequestParam(required = false) String container) {
216 Gson gson = new Gson();
217 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
218 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
219 .getInstance(IForwardingStaticRouting.class, containerName,
221 if (staticRouting == null) {
224 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
225 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
226 .getStaticRouteConfigs();
227 if (routeConfigs == null) {
230 for (StaticRouteConfig conf : routeConfigs.values()) {
231 Map<String, String> staticRoute = new HashMap<String, String>();
232 staticRoute.put("name", conf.getName());
233 staticRoute.put("staticRoute", conf.getStaticRoute());
234 staticRoute.put("nextHopType", conf.getNextHopType());
235 staticRoute.put("nextHop", conf.getNextHop());
236 staticRoute.put("json", gson.toJson(conf));
237 staticRoutes.add(staticRoute);
239 DevicesJsonBean result = new DevicesJsonBean();
240 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
241 result.setNodeData(staticRoutes);
245 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
247 public StatusJsonBean addStaticRoute(
248 @RequestParam("routeName") String routeName,
249 @RequestParam("staticRoute") String staticRoute,
250 @RequestParam("nextHop") String nextHop,
251 HttpServletRequest request, @RequestParam(required = false) String container) {
252 if (!authorize(UserLevel.NETWORKADMIN, request)) {
253 return unauthorizedMessage();
256 StatusJsonBean result = new StatusJsonBean();
257 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
259 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
260 .getInstance(IForwardingStaticRouting.class, containerName,
262 StaticRouteConfig config = new StaticRouteConfig();
263 config.setName(routeName);
264 config.setStaticRoute(staticRoute);
265 config.setNextHop(nextHop);
266 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
267 if (addStaticRouteResult.isSuccess()) {
268 result.setStatus(true);
269 result.setMessage("Static Route saved successfully");
271 result.setStatus(false);
272 result.setMessage(addStaticRouteResult.getDescription());
274 } catch (Exception e) {
275 result.setStatus(false);
276 result.setMessage("Error - " + e.getMessage());
281 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
283 public StatusJsonBean deleteStaticRoute(
284 @RequestParam("routesToDelete") String routesToDelete,
285 HttpServletRequest request, @RequestParam(required = false) String container) {
286 if (!authorize(UserLevel.NETWORKADMIN, request)) {
287 return unauthorizedMessage();
290 StatusJsonBean resultBean = new StatusJsonBean();
291 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
293 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
294 .getInstance(IForwardingStaticRouting.class, containerName,
296 String[] routes = routesToDelete.split(",");
298 resultBean.setStatus(true);
300 .setMessage("Successfully deleted selected static routes");
301 for (String route : routes) {
302 result = staticRouting.removeStaticRoute(route);
303 if (!result.isSuccess()) {
304 resultBean.setStatus(false);
305 resultBean.setMessage(result.getDescription());
309 } catch (Exception e) {
310 resultBean.setStatus(false);
312 .setMessage("Error occurred while deleting static routes. "
318 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
320 public DevicesJsonBean getSubnetGateways(HttpServletRequest request, @RequestParam(required = false) String container) {
321 Gson gson = new Gson();
322 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
323 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
324 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
325 .getInstance(ISwitchManager.class, containerName, this);
326 if (switchManager != null) {
327 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
328 Map<String, String> subnet = new HashMap<String, String>();
329 subnet.put("name", conf.getName());
330 subnet.put("subnet", conf.getSubnet());
331 subnet.put("json", gson.toJson(conf));
335 DevicesJsonBean result = new DevicesJsonBean();
336 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
337 result.setNodeData(subnets);
341 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
343 public StatusJsonBean addSubnetGateways(
344 @RequestParam("gatewayName") String gatewayName,
345 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
346 HttpServletRequest request, @RequestParam(required = false) String container) {
347 if (!authorize(UserLevel.NETWORKADMIN, request)) {
348 return unauthorizedMessage();
351 StatusJsonBean resultBean = new StatusJsonBean();
352 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
354 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
355 .getInstance(ISwitchManager.class, containerName, this);
356 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
357 gatewayIPAddress, new ArrayList<String>());
358 Status result = switchManager.addSubnet(cfgObject);
359 if (result.isSuccess()) {
360 resultBean.setStatus(true);
361 resultBean.setMessage("Added gateway address successfully");
363 resultBean.setStatus(false);
364 resultBean.setMessage(result.getDescription());
366 } catch (Exception e) {
367 resultBean.setStatus(false);
368 resultBean.setMessage(e.getMessage());
373 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
375 public StatusJsonBean deleteSubnetGateways(
376 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
377 HttpServletRequest request, @RequestParam(required = false) String container) {
378 if (!authorize(UserLevel.NETWORKADMIN, request)) {
379 return unauthorizedMessage();
382 StatusJsonBean resultBean = new StatusJsonBean();
383 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
385 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
386 .getInstance(ISwitchManager.class, containerName, this);
387 String[] subnets = gatewaysToDelete.split(",");
388 resultBean.setStatus(true);
389 resultBean.setMessage("Added gateway address successfully");
390 for (String subnet : subnets) {
391 Status result = switchManager.removeSubnet(subnet);
392 if (!result.isSuccess()) {
393 resultBean.setStatus(false);
394 resultBean.setMessage(result.getDescription());
398 } catch (Exception e) {
399 resultBean.setStatus(false);
400 resultBean.setMessage(e.getMessage());
405 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
407 public StatusJsonBean addSubnetGatewayPort(
408 @RequestParam("portsName") String portsName,
409 @RequestParam("ports") String ports,
410 @RequestParam("nodeId") String nodeId,
411 HttpServletRequest request, @RequestParam(required = false) String container) {
412 if (!authorize(UserLevel.NETWORKADMIN, request)) {
413 return unauthorizedMessage();
416 StatusJsonBean resultBean = new StatusJsonBean();
417 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
419 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
420 .getInstance(ISwitchManager.class, containerName, this);
421 Status result = switchManager.addPortsToSubnet(portsName, nodeId
424 if (result.isSuccess()) {
425 resultBean.setStatus(true);
427 .setMessage("Added ports to subnet gateway address successfully");
429 resultBean.setStatus(false);
430 resultBean.setMessage(result.getDescription());
432 } catch (Exception e) {
433 resultBean.setStatus(false);
434 resultBean.setMessage(e.getMessage());
439 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
441 public StatusJsonBean deleteSubnetGatewayPort(
442 @RequestParam("gatewayName") String gatewayName,
443 @RequestParam("nodePort") String nodePort,
444 HttpServletRequest request, @RequestParam(required = false) String container) {
445 if (!authorize(UserLevel.NETWORKADMIN, request)) {
446 return unauthorizedMessage();
449 StatusJsonBean resultBean = new StatusJsonBean();
450 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
452 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
453 .getInstance(ISwitchManager.class, containerName, this);
454 Status result = switchManager.removePortsFromSubnet(gatewayName,
457 if (result.isSuccess()) {
458 resultBean.setStatus(true);
460 .setMessage("Deleted port from subnet gateway address successfully");
462 resultBean.setStatus(false);
463 resultBean.setMessage(result.getDescription());
465 } catch (Exception e) {
466 resultBean.setStatus(false);
467 resultBean.setMessage(e.getMessage());
472 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
474 public DevicesJsonBean getSpanPorts(HttpServletRequest request, @RequestParam(required = false) String container) {
475 Gson gson = new Gson();
476 List<String> spanConfigs_json = new ArrayList<String>();
477 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
478 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
479 .getInstance(ISwitchManager.class, containerName, this);
480 if (switchManager != null) {
481 for (SpanConfig conf : switchManager.getSpanConfigList()) {
482 spanConfigs_json.add(gson.toJson(conf));
485 ObjectMapper mapper = new ObjectMapper();
486 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
487 for (String config_json : spanConfigs_json) {
489 @SuppressWarnings("unchecked")
490 Map<String, String> config_data = mapper.readValue(config_json,
492 Map<String, String> config = new HashMap<String, String>();
493 for (String name : config_data.keySet()) {
494 config.put(name, config_data.get(name));
495 // Add switch name value (non-configuration field)
496 config.put("nodeName",
497 getNodeDesc(config_data.get("nodeId"), containerName));
499 config.put("json", config_json);
500 spanConfigs.add(config);
501 } catch (Exception e) {
502 // TODO: Handle the exception.
505 DevicesJsonBean result = new DevicesJsonBean();
506 result.setColumnNames(SpanConfig.getGuiFieldsNames());
507 result.setNodeData(spanConfigs);
511 @RequestMapping(value = "/nodeports")
513 public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
514 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
515 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
516 .getInstance(ISwitchManager.class, containerName, this);
517 if (switchManager == null) {
521 Map<String, Object> nodes = new HashMap<String, Object>();
522 Map<Short, String> port;
524 for (Switch node : switchManager.getNetworkDevices()) {
525 port = new HashMap<Short, String>(); // new port
526 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
528 if (nodeConnectorSet != null)
529 for (NodeConnector nodeConnector : nodeConnectorSet) {
530 String nodeConnectorName = ((Name) switchManager
531 .getNodeConnectorProp(nodeConnector,
532 Name.NamePropName)).getValue();
533 port.put((Short) nodeConnector.getID(), nodeConnectorName
534 + "(" + nodeConnector.getID() + ")");
537 nodes.put(node.getNode().toString(), port);
543 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
545 public StatusJsonBean addSpanPort(
546 @RequestParam("jsonData") String jsonData,
547 HttpServletRequest request, @RequestParam(required = false) String container) {
548 if (!authorize(UserLevel.NETWORKADMIN, request)) {
549 return unauthorizedMessage();
552 StatusJsonBean resultBean = new StatusJsonBean();
554 Gson gson = new Gson();
555 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
556 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
557 .getInstance(ISwitchManager.class, containerName, this);
558 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
559 Status result = switchManager.addSpanConfig(cfgObject);
560 if (result.isSuccess()) {
561 resultBean.setStatus(true);
562 resultBean.setMessage("SPAN Port added successfully");
564 resultBean.setStatus(false);
565 resultBean.setMessage(result.getDescription());
567 } catch (Exception e) {
568 resultBean.setStatus(false);
569 resultBean.setMessage("Error occurred while adding span port. "
575 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
577 public StatusJsonBean deleteSpanPorts(
578 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
579 HttpServletRequest request, @RequestParam(required = false) String container) {
580 if (!authorize(UserLevel.NETWORKADMIN, request)) {
581 return unauthorizedMessage();
584 StatusJsonBean resultBean = new StatusJsonBean();
586 Gson gson = new Gson();
587 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
588 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
589 .getInstance(ISwitchManager.class, containerName, this);
590 String[] spans = spanPortsToDelete.split("###");
591 resultBean.setStatus(true);
592 resultBean.setMessage("SPAN Port(s) deleted successfully");
593 for (String span : spans) {
594 if (!span.isEmpty()) {
595 SpanConfig cfgObject = gson
596 .fromJson(span, SpanConfig.class);
597 Status result = switchManager.removeSpanConfig(cfgObject);
598 if (!result.isSuccess()) {
599 resultBean.setStatus(false);
600 resultBean.setMessage(result.getDescription());
605 } catch (Exception e) {
606 resultBean.setStatus(false);
607 resultBean.setMessage("Error occurred while deleting span port. "
613 private String getNodeDesc(String nodeId, String containerName) {
614 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
615 .getInstance(ISwitchManager.class, containerName, this);
616 String description = "";
617 if (switchManager != null) {
618 description = switchManager.getNodeDescription(Node
619 .fromString(nodeId));
621 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
626 * Is the operation permitted for the given level
630 private boolean authorize(UserLevel level, HttpServletRequest request) {
631 IUserManager userManager = (IUserManager) ServiceHelper
632 .getGlobalInstance(IUserManager.class, this);
633 if (userManager == null) {
637 String username = request.getUserPrincipal().getName();
638 UserLevel userLevel = userManager.getUserLevel(username);
639 if (userLevel.toNumber() <= level.toNumber()) {
645 private StatusJsonBean unauthorizedMessage() {
646 StatusJsonBean message = new StatusJsonBean();
647 message.setStatus(false);
648 message.setMessage("Operation not authorized");
652 @RequestMapping(value = "login")
653 public String login(final HttpServletRequest request,
654 final HttpServletResponse response) {
655 // response.setHeader("X-Page-Location", "/login");
657 * IUserManager userManager = (IUserManager) ServiceHelper
658 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
659 * null) { return "User Manager is not available"; }
661 * String username = request.getUserPrincipal().getName();
664 * model.addAttribute("username", username); model.addAttribute("role",
665 * userManager.getUserLevel(username).toNumber());
667 return "forward:" + "/";