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.IDaylightWeb;
25 import org.springframework.stereotype.Controller;
26 import org.springframework.web.bind.annotation.RequestMapping;
27 import org.springframework.web.bind.annotation.RequestMethod;
28 import org.springframework.web.bind.annotation.RequestParam;
29 import org.springframework.web.bind.annotation.ResponseBody;
30 import org.opendaylight.controller.forwarding.staticrouting.IForwardingStaticRouting;
31 import org.opendaylight.controller.forwarding.staticrouting.StaticRouteConfig;
32 import org.opendaylight.controller.sal.authorization.UserLevel;
33 import org.opendaylight.controller.sal.core.Config;
34 import org.opendaylight.controller.sal.core.Name;
35 import org.opendaylight.controller.sal.core.Node;
36 import org.opendaylight.controller.sal.core.NodeConnector;
37 import org.opendaylight.controller.sal.core.Tier;
38 import org.opendaylight.controller.sal.utils.GlobalConstants;
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;
58 private final String containerName = GlobalConstants.DEFAULT.toString();
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() {
87 Gson gson = new Gson();
88 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
89 .getInstance(ISwitchManager.class, containerName, this);
90 List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
91 for (Switch device : switchManager.getNetworkDevices()) {
92 HashMap<String, String> nodeDatum = new HashMap<String, String>();
93 Node node = device.getNode();
94 Tier tier = (Tier) switchManager.getNodeProp(node,
97 nodeDatum.put("containerName", containerName);
98 nodeDatum.put("nodeName", switchManager.getNodeDescription(node));
99 nodeDatum.put("nodeId", node.toString());
100 int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
102 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
103 + " (Tier-" + tierNumber + ")");
104 nodeDatum.put("tier", tierNumber + "");
105 SwitchConfig sc = switchManager.getSwitchConfig(device.getNode()
107 String modeStr = (sc != null) ? sc.getMode() : "0";
108 nodeDatum.put("mode", modeStr);
110 nodeDatum.put("json", gson.toJson(nodeDatum));
112 HexEncode.bytesToHexString(device.getDataLayerAddress()));
113 StringBuffer sb1 = new StringBuffer();
114 Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
115 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
116 Map<Short, String> portList = new HashMap<Short, String>();
117 for (NodeConnector nodeConnector : nodeConnectorSet) {
118 String nodeConnectorNumberToStr = nodeConnector.getID().toString();
119 Name ncName = ((Name) switchManager.getNodeConnectorProp(
120 nodeConnector, Name.NamePropName));
121 Config portStatus = ((Config) switchManager
122 .getNodeConnectorProp(nodeConnector,
123 Config.ConfigPropName));
125 String nodeConnectorName = (ncName != null) ? ncName.getValue()
127 nodeConnectorName += " ("+nodeConnector.getID()+")";
129 if (portStatus != null) {
130 if (portStatus.getValue() == Config.ADMIN_UP) {
131 nodeConnectorName = "<span style='color:green;'>"+nodeConnectorName+"</span>";
132 } else if (portStatus.getValue() == Config.ADMIN_DOWN) {
133 nodeConnectorName = "<span style='color:red;'>"+nodeConnectorName+"</span>";
137 portList.put(Short.parseShort(nodeConnectorNumberToStr),
141 Map<Short, String> sortedPortList = new TreeMap<Short, String>(portList);
143 for (Entry<Short, String> e : sortedPortList.entrySet()) {
144 sb1.append(e.getValue());
148 nodeDatum.put("ports", sb1.toString());
149 nodeData.add(nodeDatum);
151 DevicesJsonBean result = new DevicesJsonBean();
152 result.setNodeData(nodeData);
153 List<String> columnNames = new ArrayList<String>();
154 columnNames.add("Node ID");
155 columnNames.add("Node Name");
156 columnNames.add("Tier");
157 columnNames.add("Mac Address");
158 columnNames.add("Ports");
159 columnNames.add("Port Status");
161 result.setColumnNames(columnNames);
165 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
167 public List<String> getTiers() {
168 return TierHelper.getTiers();
171 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
173 public StatusJsonBean updateLearntNode(
174 @RequestParam("nodeName") String nodeName,
175 @RequestParam("nodeId") String nodeId,
176 @RequestParam("tier") String tier,
177 @RequestParam("operationMode") String operationMode,
178 HttpServletRequest request) {
179 if (!authorize(UserLevel.NETWORKADMIN, request)) {
180 return unauthorizedMessage();
183 StatusJsonBean resultBean = new StatusJsonBean();
185 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
186 .getInstance(ISwitchManager.class, containerName, this);
187 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
189 switchManager.updateSwitchConfig(cfg);
190 resultBean.setStatus(true);
191 resultBean.setMessage("Updated node information successfully");
192 } catch (Exception e) {
193 resultBean.setStatus(false);
194 resultBean.setMessage("Error updating node information. "
200 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
202 public DevicesJsonBean getStaticRoutes() {
203 Gson gson = new Gson();
204 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
205 .getInstance(IForwardingStaticRouting.class, containerName,
207 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
208 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
209 .getStaticRouteConfigs();
210 if (routeConfigs == null) {
213 for (StaticRouteConfig conf : routeConfigs.values()) {
214 Map<String, String> staticRoute = new HashMap<String, String>();
215 staticRoute.put("name", conf.getName());
216 staticRoute.put("staticRoute", conf.getStaticRoute());
217 staticRoute.put("nextHopType", conf.getNextHopType());
218 staticRoute.put("nextHop", conf.getNextHop());
219 staticRoute.put("json", gson.toJson(conf));
220 staticRoutes.add(staticRoute);
222 DevicesJsonBean result = new DevicesJsonBean();
223 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
224 result.setNodeData(staticRoutes);
228 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
230 public StatusJsonBean addStaticRoute(
231 @RequestParam("routeName") String routeName,
232 @RequestParam("staticRoute") String staticRoute,
233 @RequestParam("nextHop") String nextHop, HttpServletRequest request) {
234 if (!authorize(UserLevel.NETWORKADMIN, request)) {
235 return unauthorizedMessage();
238 StatusJsonBean result = new StatusJsonBean();
240 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
241 .getInstance(IForwardingStaticRouting.class, containerName,
243 StaticRouteConfig config = new StaticRouteConfig();
244 config.setName(routeName);
245 config.setStaticRoute(staticRoute);
246 config.setNextHop(nextHop);
247 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
248 if (addStaticRouteResult.isSuccess()) {
249 result.setStatus(true);
250 result.setMessage("Static Route saved successfully");
252 result.setStatus(false);
253 result.setMessage(addStaticRouteResult.getDescription());
255 } catch (Exception e) {
256 result.setStatus(false);
257 result.setMessage("Error - " + e.getMessage());
262 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
264 public StatusJsonBean deleteStaticRoute(
265 @RequestParam("routesToDelete") String routesToDelete,
266 HttpServletRequest request) {
267 if (!authorize(UserLevel.NETWORKADMIN, request)) {
268 return unauthorizedMessage();
271 StatusJsonBean resultBean = new StatusJsonBean();
273 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
274 .getInstance(IForwardingStaticRouting.class, containerName,
276 String[] routes = routesToDelete.split(",");
278 resultBean.setStatus(true);
280 .setMessage("Successfully deleted selected static routes");
281 for (String route : routes) {
282 result = staticRouting.removeStaticRoute(route);
283 if (!result.isSuccess()) {
284 resultBean.setStatus(false);
285 resultBean.setMessage(result.getDescription());
289 } catch (Exception e) {
290 resultBean.setStatus(false);
292 .setMessage("Error occurred while deleting static routes. "
298 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
300 public DevicesJsonBean getSubnetGateways() {
301 Gson gson = new Gson();
302 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
303 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
304 .getInstance(ISwitchManager.class, containerName, this);
305 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
306 Map<String, String> subnet = new HashMap<String, String>();
307 subnet.put("name", conf.getName());
308 subnet.put("subnet", conf.getSubnet());
309 subnet.put("json", gson.toJson(conf));
312 DevicesJsonBean result = new DevicesJsonBean();
313 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
314 result.setNodeData(subnets);
318 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
320 public StatusJsonBean addSubnetGateways(
321 @RequestParam("gatewayName") String gatewayName,
322 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
323 HttpServletRequest request) {
324 if (!authorize(UserLevel.NETWORKADMIN, request)) {
325 return unauthorizedMessage();
328 StatusJsonBean resultBean = new StatusJsonBean();
330 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
331 .getInstance(ISwitchManager.class, containerName, this);
332 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
333 gatewayIPAddress, new ArrayList<String>());
334 Status result = switchManager.addSubnet(cfgObject);
335 if (result.isSuccess()) {
336 resultBean.setStatus(true);
337 resultBean.setMessage("Added gateway address successfully");
339 resultBean.setStatus(false);
340 resultBean.setMessage(result.getDescription());
342 } catch (Exception e) {
343 resultBean.setStatus(false);
344 resultBean.setMessage(e.getMessage());
349 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
351 public StatusJsonBean deleteSubnetGateways(
352 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
353 HttpServletRequest request) {
354 if (!authorize(UserLevel.NETWORKADMIN, request)) {
355 return unauthorizedMessage();
358 StatusJsonBean resultBean = new StatusJsonBean();
360 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
361 .getInstance(ISwitchManager.class, containerName, this);
362 String[] subnets = gatewaysToDelete.split(",");
363 resultBean.setStatus(true);
364 resultBean.setMessage("Added gateway address successfully");
365 for (String subnet : subnets) {
366 Status result = switchManager.removeSubnet(subnet);
367 if (!result.isSuccess()) {
368 resultBean.setStatus(false);
369 resultBean.setMessage(result.getDescription());
373 } catch (Exception e) {
374 resultBean.setStatus(false);
375 resultBean.setMessage(e.getMessage());
380 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
382 public StatusJsonBean addSubnetGatewayPort(
383 @RequestParam("portsName") String portsName,
384 @RequestParam("ports") String ports,
385 @RequestParam("nodeId") String nodeId, HttpServletRequest request) {
386 if (!authorize(UserLevel.NETWORKADMIN, request)) {
387 return unauthorizedMessage();
390 StatusJsonBean resultBean = new StatusJsonBean();
392 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
393 .getInstance(ISwitchManager.class, containerName, this);
394 Status result = switchManager.addPortsToSubnet(portsName, nodeId
397 if (result.isSuccess()) {
398 resultBean.setStatus(true);
400 .setMessage("Added ports to subnet gateway address successfully");
402 resultBean.setStatus(false);
403 resultBean.setMessage(result.getDescription());
405 } catch (Exception e) {
406 resultBean.setStatus(false);
407 resultBean.setMessage(e.getMessage());
412 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
414 public StatusJsonBean deleteSubnetGatewayPort(
415 @RequestParam("gatewayName") String gatewayName,
416 @RequestParam("nodePort") String nodePort,
417 HttpServletRequest request) {
418 if (!authorize(UserLevel.NETWORKADMIN, request)) {
419 return unauthorizedMessage();
422 StatusJsonBean resultBean = new StatusJsonBean();
424 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
425 .getInstance(ISwitchManager.class, containerName, this);
426 Status result = switchManager.removePortsFromSubnet(gatewayName,
429 if (result.isSuccess()) {
430 resultBean.setStatus(true);
432 .setMessage("Deleted port from subnet gateway address successfully");
434 resultBean.setStatus(false);
435 resultBean.setMessage(result.getDescription());
437 } catch (Exception e) {
438 resultBean.setStatus(false);
439 resultBean.setMessage(e.getMessage());
444 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
446 public DevicesJsonBean getSpanPorts() {
447 Gson gson = new Gson();
448 List<String> spanConfigs_json = new ArrayList<String>();
449 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
450 .getInstance(ISwitchManager.class, containerName, this);
451 for (SpanConfig conf : switchManager.getSpanConfigList()) {
452 spanConfigs_json.add(gson.toJson(conf));
454 ObjectMapper mapper = new ObjectMapper();
455 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
456 for (String config_json : spanConfigs_json) {
458 @SuppressWarnings("unchecked")
459 Map<String, String> config_data = mapper.readValue(config_json,
461 Map<String, String> config = new HashMap<String, String>();
462 for (String name : config_data.keySet()) {
463 config.put(name, config_data.get(name));
464 // Add switch name value (non-configuration field)
465 config.put("nodeName",
466 getNodeDesc(config_data.get("nodeId")));
468 config.put("json", config_json);
469 spanConfigs.add(config);
470 } catch (Exception e) {
471 // TODO: Handle the exception.
474 DevicesJsonBean result = new DevicesJsonBean();
475 result.setColumnNames(SpanConfig.getGuiFieldsNames());
476 result.setNodeData(spanConfigs);
480 @RequestMapping(value = "/nodeports")
482 public Map<String, Object> getNodePorts() {
483 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
484 .getInstance(ISwitchManager.class, containerName, this);
485 if (switchManager == null)
488 Map<String, Object> nodes = new HashMap<String, Object>();
489 Map<Short, String> port;
491 for (Switch node : switchManager.getNetworkDevices()) {
492 port = new HashMap<Short, String>(); // new port
493 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
495 if (nodeConnectorSet != null)
496 for (NodeConnector nodeConnector : nodeConnectorSet) {
497 String nodeConnectorName = ((Name) switchManager
498 .getNodeConnectorProp(nodeConnector,
499 Name.NamePropName)).getValue();
500 port.put((Short) nodeConnector.getID(), nodeConnectorName
501 + "(" + nodeConnector.getID() + ")");
504 nodes.put(node.getNode().toString(), port);
510 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
512 public StatusJsonBean addSpanPort(
513 @RequestParam("jsonData") String jsonData,
514 HttpServletRequest request) {
515 if (!authorize(UserLevel.NETWORKADMIN, request)) {
516 return unauthorizedMessage();
519 StatusJsonBean resultBean = new StatusJsonBean();
521 Gson gson = new Gson();
522 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
523 .getInstance(ISwitchManager.class, containerName, this);
524 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
525 Status result = switchManager.addSpanConfig(cfgObject);
526 if (result.isSuccess()) {
527 resultBean.setStatus(true);
528 resultBean.setMessage("SPAN Port added successfully");
530 resultBean.setStatus(false);
531 resultBean.setMessage(result.getDescription());
533 } catch (Exception e) {
534 resultBean.setStatus(false);
535 resultBean.setMessage("Error occurred while adding span port. "
541 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
543 public StatusJsonBean deleteSpanPorts(
544 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
545 HttpServletRequest request) {
546 if (!authorize(UserLevel.NETWORKADMIN, request)) {
547 return unauthorizedMessage();
550 StatusJsonBean resultBean = new StatusJsonBean();
552 Gson gson = new Gson();
553 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
554 .getInstance(ISwitchManager.class, containerName, this);
555 String[] spans = spanPortsToDelete.split("###");
556 resultBean.setStatus(true);
557 resultBean.setMessage("SPAN Port(s) deleted successfully");
558 for (String span : spans) {
559 if (!span.isEmpty()) {
560 SpanConfig cfgObject = gson
561 .fromJson(span, SpanConfig.class);
562 Status result = switchManager.removeSpanConfig(cfgObject);
563 if (!result.isSuccess()) {
564 resultBean.setStatus(false);
565 resultBean.setMessage(result.getDescription());
570 } catch (Exception e) {
571 resultBean.setStatus(false);
572 resultBean.setMessage("Error occurred while deleting span port. "
578 private String getNodeDesc(String nodeId) {
579 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
580 .getInstance(ISwitchManager.class, containerName, this);
581 String description = "";
582 if (switchManager != null) {
583 description = switchManager.getNodeDescription(Node
584 .fromString(nodeId));
586 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
591 * Is the operation permitted for the given level
595 private boolean authorize(UserLevel level, HttpServletRequest request) {
596 IUserManager userManager = (IUserManager) ServiceHelper
597 .getGlobalInstance(IUserManager.class, this);
598 if (userManager == null) {
602 String username = request.getUserPrincipal().getName();
603 UserLevel userLevel = userManager.getUserLevel(username);
604 if (userLevel.toNumber() <= level.toNumber()) {
610 private StatusJsonBean unauthorizedMessage() {
611 StatusJsonBean message = new StatusJsonBean();
612 message.setStatus(false);
613 message.setMessage("Operation not authorized");
617 @RequestMapping(value = "login")
618 public String login(final HttpServletRequest request,
619 final HttpServletResponse response) {
620 // response.setHeader("X-Page-Location", "/login");
622 * IUserManager userManager = (IUserManager) ServiceHelper
623 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
624 * null) { return "User Manager is not available"; }
626 * String username = request.getUserPrincipal().getName();
629 * model.addAttribute("username", username); model.addAttribute("role",
630 * userManager.getUserLevel(username).toNumber());
632 return "forward:" + "/";