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 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", switchManager.getNodeDescription(node));
100 nodeDatum.put("nodeId", node.toString());
101 int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
103 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
104 + " (Tier-" + tierNumber + ")");
105 nodeDatum.put("tier", tierNumber + "");
106 SwitchConfig sc = switchManager.getSwitchConfig(device.getNode()
108 String modeStr = (sc != null) ? sc.getMode() : "0";
109 nodeDatum.put("mode", modeStr);
111 nodeDatum.put("json", gson.toJson(nodeDatum));
113 HexEncode.bytesToHexString(device.getDataLayerAddress()));
114 StringBuffer sb1 = new StringBuffer();
115 Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
116 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
117 Map<Short, String> portList = new HashMap<Short, String>();
118 for (NodeConnector nodeConnector : nodeConnectorSet) {
119 String nodeConnectorNumberToStr = nodeConnector.getID().toString();
120 Name ncName = ((Name) switchManager.getNodeConnectorProp(
121 nodeConnector, Name.NamePropName));
122 Config portStatus = ((Config) switchManager
123 .getNodeConnectorProp(nodeConnector,
124 Config.ConfigPropName));
126 String nodeConnectorName = (ncName != null) ? ncName.getValue()
128 nodeConnectorName += " ("+nodeConnector.getID()+")";
130 if (portStatus != null) {
131 if (portStatus.getValue() == Config.ADMIN_UP) {
132 nodeConnectorName = "<span style='color:green;'>"+nodeConnectorName+"</span>";
133 } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
134 nodeConnectorName = "<span style='color:red;'>"+nodeConnectorName+"</span>";
138 portList.put(Short.parseShort(nodeConnectorNumberToStr),
142 Map<Short, String> sortedPortList = new TreeMap<Short, String>(portList);
144 for (Entry<Short, String> e : sortedPortList.entrySet()) {
145 sb1.append(e.getValue());
149 nodeDatum.put("ports", sb1.toString());
150 nodeData.add(nodeDatum);
152 DevicesJsonBean result = new DevicesJsonBean();
153 result.setNodeData(nodeData);
154 List<String> columnNames = new ArrayList<String>();
155 columnNames.add("Node ID");
156 columnNames.add("Node Name");
157 columnNames.add("Tier");
158 columnNames.add("Mac Address");
159 columnNames.add("Ports");
160 columnNames.add("Port Status");
162 result.setColumnNames(columnNames);
166 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
168 public List<String> getTiers() {
169 return TierHelper.getTiers();
172 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
174 public StatusJsonBean updateLearntNode(
175 @RequestParam("nodeName") String nodeName,
176 @RequestParam("nodeId") String nodeId,
177 @RequestParam("tier") String tier,
178 @RequestParam("operationMode") String operationMode,
179 HttpServletRequest request, @RequestParam(required = false) String container) {
180 if (!authorize(UserLevel.NETWORKADMIN, request)) {
181 return unauthorizedMessage();
184 StatusJsonBean resultBean = new StatusJsonBean();
185 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
187 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
188 .getInstance(ISwitchManager.class, containerName, this);
189 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
191 switchManager.updateSwitchConfig(cfg);
192 resultBean.setStatus(true);
193 resultBean.setMessage("Updated node information successfully");
194 } catch (Exception e) {
195 resultBean.setStatus(false);
196 resultBean.setMessage("Error updating node information. "
202 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
204 public DevicesJsonBean getStaticRoutes(HttpServletRequest request, @RequestParam(required = false) String container) {
205 Gson gson = new Gson();
206 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
207 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
208 .getInstance(IForwardingStaticRouting.class, containerName,
210 if (staticRouting == null) {
213 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
214 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
215 .getStaticRouteConfigs();
216 if (routeConfigs == null) {
219 for (StaticRouteConfig conf : routeConfigs.values()) {
220 Map<String, String> staticRoute = new HashMap<String, String>();
221 staticRoute.put("name", conf.getName());
222 staticRoute.put("staticRoute", conf.getStaticRoute());
223 staticRoute.put("nextHopType", conf.getNextHopType());
224 staticRoute.put("nextHop", conf.getNextHop());
225 staticRoute.put("json", gson.toJson(conf));
226 staticRoutes.add(staticRoute);
228 DevicesJsonBean result = new DevicesJsonBean();
229 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
230 result.setNodeData(staticRoutes);
234 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
236 public StatusJsonBean addStaticRoute(
237 @RequestParam("routeName") String routeName,
238 @RequestParam("staticRoute") String staticRoute,
239 @RequestParam("nextHop") String nextHop,
240 HttpServletRequest request, @RequestParam(required = false) String container) {
241 if (!authorize(UserLevel.NETWORKADMIN, request)) {
242 return unauthorizedMessage();
245 StatusJsonBean result = new StatusJsonBean();
246 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
248 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
249 .getInstance(IForwardingStaticRouting.class, containerName,
251 StaticRouteConfig config = new StaticRouteConfig();
252 config.setName(routeName);
253 config.setStaticRoute(staticRoute);
254 config.setNextHop(nextHop);
255 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
256 if (addStaticRouteResult.isSuccess()) {
257 result.setStatus(true);
258 result.setMessage("Static Route saved successfully");
260 result.setStatus(false);
261 result.setMessage(addStaticRouteResult.getDescription());
263 } catch (Exception e) {
264 result.setStatus(false);
265 result.setMessage("Error - " + e.getMessage());
270 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
272 public StatusJsonBean deleteStaticRoute(
273 @RequestParam("routesToDelete") String routesToDelete,
274 HttpServletRequest request, @RequestParam(required = false) String container) {
275 if (!authorize(UserLevel.NETWORKADMIN, request)) {
276 return unauthorizedMessage();
279 StatusJsonBean resultBean = new StatusJsonBean();
280 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
282 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
283 .getInstance(IForwardingStaticRouting.class, containerName,
285 String[] routes = routesToDelete.split(",");
287 resultBean.setStatus(true);
289 .setMessage("Successfully deleted selected static routes");
290 for (String route : routes) {
291 result = staticRouting.removeStaticRoute(route);
292 if (!result.isSuccess()) {
293 resultBean.setStatus(false);
294 resultBean.setMessage(result.getDescription());
298 } catch (Exception e) {
299 resultBean.setStatus(false);
301 .setMessage("Error occurred while deleting static routes. "
307 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
309 public DevicesJsonBean getSubnetGateways(HttpServletRequest request, @RequestParam(required = false) String container) {
310 Gson gson = new Gson();
311 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
312 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
313 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
314 .getInstance(ISwitchManager.class, containerName, this);
315 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
316 Map<String, String> subnet = new HashMap<String, String>();
317 subnet.put("name", conf.getName());
318 subnet.put("subnet", conf.getSubnet());
319 subnet.put("json", gson.toJson(conf));
322 DevicesJsonBean result = new DevicesJsonBean();
323 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
324 result.setNodeData(subnets);
328 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
330 public StatusJsonBean addSubnetGateways(
331 @RequestParam("gatewayName") String gatewayName,
332 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
333 HttpServletRequest request, @RequestParam(required = false) String container) {
334 if (!authorize(UserLevel.NETWORKADMIN, request)) {
335 return unauthorizedMessage();
338 StatusJsonBean resultBean = new StatusJsonBean();
339 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
341 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
342 .getInstance(ISwitchManager.class, containerName, this);
343 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
344 gatewayIPAddress, new ArrayList<String>());
345 Status result = switchManager.addSubnet(cfgObject);
346 if (result.isSuccess()) {
347 resultBean.setStatus(true);
348 resultBean.setMessage("Added gateway address successfully");
350 resultBean.setStatus(false);
351 resultBean.setMessage(result.getDescription());
353 } catch (Exception e) {
354 resultBean.setStatus(false);
355 resultBean.setMessage(e.getMessage());
360 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
362 public StatusJsonBean deleteSubnetGateways(
363 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
364 HttpServletRequest request, @RequestParam(required = false) String container) {
365 if (!authorize(UserLevel.NETWORKADMIN, request)) {
366 return unauthorizedMessage();
369 StatusJsonBean resultBean = new StatusJsonBean();
370 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
372 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
373 .getInstance(ISwitchManager.class, containerName, this);
374 String[] subnets = gatewaysToDelete.split(",");
375 resultBean.setStatus(true);
376 resultBean.setMessage("Added gateway address successfully");
377 for (String subnet : subnets) {
378 Status result = switchManager.removeSubnet(subnet);
379 if (!result.isSuccess()) {
380 resultBean.setStatus(false);
381 resultBean.setMessage(result.getDescription());
385 } catch (Exception e) {
386 resultBean.setStatus(false);
387 resultBean.setMessage(e.getMessage());
392 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
394 public StatusJsonBean addSubnetGatewayPort(
395 @RequestParam("portsName") String portsName,
396 @RequestParam("ports") String ports,
397 @RequestParam("nodeId") String nodeId,
398 HttpServletRequest request, @RequestParam(required = false) String container) {
399 if (!authorize(UserLevel.NETWORKADMIN, request)) {
400 return unauthorizedMessage();
403 StatusJsonBean resultBean = new StatusJsonBean();
404 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
406 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
407 .getInstance(ISwitchManager.class, containerName, this);
408 Status result = switchManager.addPortsToSubnet(portsName, nodeId
411 if (result.isSuccess()) {
412 resultBean.setStatus(true);
414 .setMessage("Added ports to subnet gateway address successfully");
416 resultBean.setStatus(false);
417 resultBean.setMessage(result.getDescription());
419 } catch (Exception e) {
420 resultBean.setStatus(false);
421 resultBean.setMessage(e.getMessage());
426 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
428 public StatusJsonBean deleteSubnetGatewayPort(
429 @RequestParam("gatewayName") String gatewayName,
430 @RequestParam("nodePort") String nodePort,
431 HttpServletRequest request, @RequestParam(required = false) String container) {
432 if (!authorize(UserLevel.NETWORKADMIN, request)) {
433 return unauthorizedMessage();
436 StatusJsonBean resultBean = new StatusJsonBean();
437 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
439 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
440 .getInstance(ISwitchManager.class, containerName, this);
441 Status result = switchManager.removePortsFromSubnet(gatewayName,
444 if (result.isSuccess()) {
445 resultBean.setStatus(true);
447 .setMessage("Deleted port from subnet gateway address successfully");
449 resultBean.setStatus(false);
450 resultBean.setMessage(result.getDescription());
452 } catch (Exception e) {
453 resultBean.setStatus(false);
454 resultBean.setMessage(e.getMessage());
459 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
461 public DevicesJsonBean getSpanPorts(HttpServletRequest request, @RequestParam(required = false) String container) {
462 Gson gson = new Gson();
463 List<String> spanConfigs_json = new ArrayList<String>();
464 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
465 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
466 .getInstance(ISwitchManager.class, containerName, this);
467 for (SpanConfig conf : switchManager.getSpanConfigList()) {
468 spanConfigs_json.add(gson.toJson(conf));
470 ObjectMapper mapper = new ObjectMapper();
471 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
472 for (String config_json : spanConfigs_json) {
474 @SuppressWarnings("unchecked")
475 Map<String, String> config_data = mapper.readValue(config_json,
477 Map<String, String> config = new HashMap<String, String>();
478 for (String name : config_data.keySet()) {
479 config.put(name, config_data.get(name));
480 // Add switch name value (non-configuration field)
481 config.put("nodeName",
482 getNodeDesc(config_data.get("nodeId"), containerName));
484 config.put("json", config_json);
485 spanConfigs.add(config);
486 } catch (Exception e) {
487 // TODO: Handle the exception.
490 DevicesJsonBean result = new DevicesJsonBean();
491 result.setColumnNames(SpanConfig.getGuiFieldsNames());
492 result.setNodeData(spanConfigs);
496 @RequestMapping(value = "/nodeports")
498 public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
499 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
500 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
501 .getInstance(ISwitchManager.class, containerName, this);
502 if (switchManager == null)
505 Map<String, Object> nodes = new HashMap<String, Object>();
506 Map<Short, String> port;
508 for (Switch node : switchManager.getNetworkDevices()) {
509 port = new HashMap<Short, String>(); // new port
510 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
512 if (nodeConnectorSet != null)
513 for (NodeConnector nodeConnector : nodeConnectorSet) {
514 String nodeConnectorName = ((Name) switchManager
515 .getNodeConnectorProp(nodeConnector,
516 Name.NamePropName)).getValue();
517 port.put((Short) nodeConnector.getID(), nodeConnectorName
518 + "(" + nodeConnector.getID() + ")");
521 nodes.put(node.getNode().toString(), port);
527 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
529 public StatusJsonBean addSpanPort(
530 @RequestParam("jsonData") String jsonData,
531 HttpServletRequest request, @RequestParam(required = false) String container) {
532 if (!authorize(UserLevel.NETWORKADMIN, request)) {
533 return unauthorizedMessage();
536 StatusJsonBean resultBean = new StatusJsonBean();
538 Gson gson = new Gson();
539 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
540 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
541 .getInstance(ISwitchManager.class, containerName, this);
542 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
543 Status result = switchManager.addSpanConfig(cfgObject);
544 if (result.isSuccess()) {
545 resultBean.setStatus(true);
546 resultBean.setMessage("SPAN Port added successfully");
548 resultBean.setStatus(false);
549 resultBean.setMessage(result.getDescription());
551 } catch (Exception e) {
552 resultBean.setStatus(false);
553 resultBean.setMessage("Error occurred while adding span port. "
559 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
561 public StatusJsonBean deleteSpanPorts(
562 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
563 HttpServletRequest request, @RequestParam(required = false) String container) {
564 if (!authorize(UserLevel.NETWORKADMIN, request)) {
565 return unauthorizedMessage();
568 StatusJsonBean resultBean = new StatusJsonBean();
570 Gson gson = new Gson();
571 String containerName = DaylightWebUtil.getAuthorizedContainer(request, container, this);
572 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
573 .getInstance(ISwitchManager.class, containerName, this);
574 String[] spans = spanPortsToDelete.split("###");
575 resultBean.setStatus(true);
576 resultBean.setMessage("SPAN Port(s) deleted successfully");
577 for (String span : spans) {
578 if (!span.isEmpty()) {
579 SpanConfig cfgObject = gson
580 .fromJson(span, SpanConfig.class);
581 Status result = switchManager.removeSpanConfig(cfgObject);
582 if (!result.isSuccess()) {
583 resultBean.setStatus(false);
584 resultBean.setMessage(result.getDescription());
589 } catch (Exception e) {
590 resultBean.setStatus(false);
591 resultBean.setMessage("Error occurred while deleting span port. "
597 private String getNodeDesc(String nodeId, String containerName) {
598 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
599 .getInstance(ISwitchManager.class, containerName, this);
600 String description = "";
601 if (switchManager != null) {
602 description = switchManager.getNodeDescription(Node
603 .fromString(nodeId));
605 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
610 * Is the operation permitted for the given level
614 private boolean authorize(UserLevel level, HttpServletRequest request) {
615 IUserManager userManager = (IUserManager) ServiceHelper
616 .getGlobalInstance(IUserManager.class, this);
617 if (userManager == null) {
621 String username = request.getUserPrincipal().getName();
622 UserLevel userLevel = userManager.getUserLevel(username);
623 if (userLevel.toNumber() <= level.toNumber()) {
629 private StatusJsonBean unauthorizedMessage() {
630 StatusJsonBean message = new StatusJsonBean();
631 message.setStatus(false);
632 message.setMessage("Operation not authorized");
636 @RequestMapping(value = "login")
637 public String login(final HttpServletRequest request,
638 final HttpServletResponse response) {
639 // response.setHeader("X-Page-Location", "/login");
641 * IUserManager userManager = (IUserManager) ServiceHelper
642 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
643 * null) { return "User Manager is not available"; }
645 * String username = request.getUserPrincipal().getName();
648 * model.addAttribute("username", username); model.addAttribute("role",
649 * userManager.getUserLevel(username).toNumber());
651 return "forward:" + "/";