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 Map<String, String> portListStatus = new HashMap<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 StringBuffer sb2 = new StringBuffer();
116 Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
117 String nodeConnectorName;
118 String nodeConnectorNumberToStr;
119 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
120 Map<Short, String> portList = new HashMap<Short, String>();
121 for (NodeConnector nodeConnector : nodeConnectorSet) {
122 nodeConnectorNumberToStr = nodeConnector.getID().toString();
123 Name ncName = ((Name) switchManager.getNodeConnectorProp(
124 nodeConnector, Name.NamePropName));
125 Config portStatus = ((Config) switchManager
126 .getNodeConnectorProp(nodeConnector,
127 Config.ConfigPropName));
128 nodeConnectorName = (ncName != null) ? ncName.getValue()
130 portList.put(Short.parseShort(nodeConnectorNumberToStr),
133 .put(nodeConnectorName, portStatus.toString());
136 Map<Short, String> sortedPortList = new TreeMap<Short, String>(
139 for (Entry<Short, String> e : sortedPortList.entrySet()) {
140 sb1.append(e.getValue() + "(" + e.getKey() + ")");
142 sb2.append(portListStatus.get(e.getValue()) + "<br>");
145 nodeDatum.put("ports", sb1.toString());
146 nodeDatum.put("portStatus", sb2.toString());
147 nodeData.add(nodeDatum);
149 DevicesJsonBean result = new DevicesJsonBean();
150 result.setNodeData(nodeData);
151 List<String> columnNames = new ArrayList<String>();
152 columnNames.add("Node ID");
153 columnNames.add("Node Name");
154 columnNames.add("Tier");
155 columnNames.add("Mac Address");
156 columnNames.add("Ports");
157 columnNames.add("Port Status");
159 result.setColumnNames(columnNames);
163 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
165 public List<String> getTiers() {
166 return TierHelper.getTiers();
169 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
171 public StatusJsonBean updateLearntNode(
172 @RequestParam("nodeName") String nodeName,
173 @RequestParam("nodeId") String nodeId,
174 @RequestParam("tier") String tier,
175 @RequestParam("operationMode") String operationMode,
176 HttpServletRequest request) {
177 if (!authorize(UserLevel.NETWORKADMIN, request)) {
178 return unauthorizedMessage();
181 StatusJsonBean resultBean = new StatusJsonBean();
183 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
184 .getInstance(ISwitchManager.class, containerName, this);
185 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
187 switchManager.updateSwitchConfig(cfg);
188 resultBean.setStatus(true);
189 resultBean.setMessage("Updated node information successfully");
190 } catch (Exception e) {
191 resultBean.setStatus(false);
192 resultBean.setMessage("Error updating node information. "
198 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
200 public DevicesJsonBean getStaticRoutes() {
201 Gson gson = new Gson();
202 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
203 .getInstance(IForwardingStaticRouting.class, containerName,
205 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
206 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
207 .getStaticRouteConfigs();
208 if (routeConfigs == null) {
211 for (StaticRouteConfig conf : routeConfigs.values()) {
212 Map<String, String> staticRoute = new HashMap<String, String>();
213 staticRoute.put("name", conf.getName());
214 staticRoute.put("staticRoute", conf.getStaticRoute());
215 staticRoute.put("nextHopType", conf.getNextHopType());
216 staticRoute.put("nextHop", conf.getNextHop());
217 staticRoute.put("json", gson.toJson(conf));
218 staticRoutes.add(staticRoute);
220 DevicesJsonBean result = new DevicesJsonBean();
221 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
222 result.setNodeData(staticRoutes);
226 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
228 public StatusJsonBean addStaticRoute(
229 @RequestParam("routeName") String routeName,
230 @RequestParam("staticRoute") String staticRoute,
231 @RequestParam("nextHop") String nextHop, HttpServletRequest request) {
232 if (!authorize(UserLevel.NETWORKADMIN, request)) {
233 return unauthorizedMessage();
236 StatusJsonBean result = new StatusJsonBean();
238 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
239 .getInstance(IForwardingStaticRouting.class, containerName,
241 StaticRouteConfig config = new StaticRouteConfig();
242 config.setName(routeName);
243 config.setStaticRoute(staticRoute);
244 config.setNextHop(nextHop);
245 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
246 if (addStaticRouteResult.isSuccess()) {
247 result.setStatus(true);
248 result.setMessage("Static Route saved successfully");
250 result.setStatus(false);
251 result.setMessage(addStaticRouteResult.getDescription());
253 } catch (Exception e) {
254 result.setStatus(false);
255 result.setMessage("Error - " + e.getMessage());
260 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
262 public StatusJsonBean deleteStaticRoute(
263 @RequestParam("routesToDelete") String routesToDelete,
264 HttpServletRequest request) {
265 if (!authorize(UserLevel.NETWORKADMIN, request)) {
266 return unauthorizedMessage();
269 StatusJsonBean resultBean = new StatusJsonBean();
271 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
272 .getInstance(IForwardingStaticRouting.class, containerName,
274 String[] routes = routesToDelete.split(",");
276 resultBean.setStatus(true);
278 .setMessage("Successfully deleted selected static routes");
279 for (String route : routes) {
280 result = staticRouting.removeStaticRoute(route);
281 if (!result.isSuccess()) {
282 resultBean.setStatus(false);
283 resultBean.setMessage(result.getDescription());
287 } catch (Exception e) {
288 resultBean.setStatus(false);
290 .setMessage("Error occurred while deleting static routes. "
296 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
298 public DevicesJsonBean getSubnetGateways() {
299 Gson gson = new Gson();
300 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
301 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
302 .getInstance(ISwitchManager.class, containerName, this);
303 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
304 Map<String, String> subnet = new HashMap<String, String>();
305 subnet.put("name", conf.getName());
306 subnet.put("subnet", conf.getSubnet());
307 subnet.put("json", gson.toJson(conf));
310 DevicesJsonBean result = new DevicesJsonBean();
311 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
312 result.setNodeData(subnets);
316 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
318 public StatusJsonBean addSubnetGateways(
319 @RequestParam("gatewayName") String gatewayName,
320 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
321 HttpServletRequest request) {
322 if (!authorize(UserLevel.NETWORKADMIN, request)) {
323 return unauthorizedMessage();
326 StatusJsonBean resultBean = new StatusJsonBean();
328 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
329 .getInstance(ISwitchManager.class, containerName, this);
330 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
331 gatewayIPAddress, new ArrayList<String>());
332 Status result = switchManager.addSubnet(cfgObject);
333 if (result.isSuccess()) {
334 resultBean.setStatus(true);
335 resultBean.setMessage("Added gateway address successfully");
337 resultBean.setStatus(false);
338 resultBean.setMessage(result.getDescription());
340 } catch (Exception e) {
341 resultBean.setStatus(false);
342 resultBean.setMessage(e.getMessage());
347 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
349 public StatusJsonBean deleteSubnetGateways(
350 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
351 HttpServletRequest request) {
352 if (!authorize(UserLevel.NETWORKADMIN, request)) {
353 return unauthorizedMessage();
356 StatusJsonBean resultBean = new StatusJsonBean();
358 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
359 .getInstance(ISwitchManager.class, containerName, this);
360 String[] subnets = gatewaysToDelete.split(",");
361 resultBean.setStatus(true);
362 resultBean.setMessage("Added gateway address successfully");
363 for (String subnet : subnets) {
364 Status result = switchManager.removeSubnet(subnet);
365 if (!result.isSuccess()) {
366 resultBean.setStatus(false);
367 resultBean.setMessage(result.getDescription());
371 } catch (Exception e) {
372 resultBean.setStatus(false);
373 resultBean.setMessage(e.getMessage());
378 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
380 public StatusJsonBean addSubnetGatewayPort(
381 @RequestParam("portsName") String portsName,
382 @RequestParam("ports") String ports,
383 @RequestParam("nodeId") String nodeId, HttpServletRequest request) {
384 if (!authorize(UserLevel.NETWORKADMIN, request)) {
385 return unauthorizedMessage();
388 StatusJsonBean resultBean = new StatusJsonBean();
390 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
391 .getInstance(ISwitchManager.class, containerName, this);
392 Status result = switchManager.addPortsToSubnet(portsName, nodeId
395 if (result.isSuccess()) {
396 resultBean.setStatus(true);
398 .setMessage("Added ports to subnet gateway address successfully");
400 resultBean.setStatus(false);
401 resultBean.setMessage(result.getDescription());
403 } catch (Exception e) {
404 resultBean.setStatus(false);
405 resultBean.setMessage(e.getMessage());
410 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
412 public StatusJsonBean deleteSubnetGatewayPort(
413 @RequestParam("gatewayName") String gatewayName,
414 @RequestParam("nodePort") String nodePort,
415 HttpServletRequest request) {
416 if (!authorize(UserLevel.NETWORKADMIN, request)) {
417 return unauthorizedMessage();
420 StatusJsonBean resultBean = new StatusJsonBean();
422 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
423 .getInstance(ISwitchManager.class, containerName, this);
424 Status result = switchManager.removePortsFromSubnet(gatewayName,
427 if (result.isSuccess()) {
428 resultBean.setStatus(true);
430 .setMessage("Deleted port from subnet gateway address successfully");
432 resultBean.setStatus(false);
433 resultBean.setMessage(result.getDescription());
435 } catch (Exception e) {
436 resultBean.setStatus(false);
437 resultBean.setMessage(e.getMessage());
442 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
444 public DevicesJsonBean getSpanPorts() {
445 Gson gson = new Gson();
446 List<String> spanConfigs_json = new ArrayList<String>();
447 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
448 .getInstance(ISwitchManager.class, containerName, this);
449 for (SpanConfig conf : switchManager.getSpanConfigList()) {
450 spanConfigs_json.add(gson.toJson(conf));
452 ObjectMapper mapper = new ObjectMapper();
453 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
454 for (String config_json : spanConfigs_json) {
456 @SuppressWarnings("unchecked")
457 Map<String, String> config_data = mapper.readValue(config_json,
459 Map<String, String> config = new HashMap<String, String>();
460 for (String name : config_data.keySet()) {
461 config.put(name, config_data.get(name));
462 // Add switch name value (non-configuration field)
463 config.put("nodeName",
464 getNodeDesc(config_data.get("nodeId")));
466 config.put("json", config_json);
467 spanConfigs.add(config);
468 } catch (Exception e) {
469 // TODO: Handle the exception.
472 DevicesJsonBean result = new DevicesJsonBean();
473 result.setColumnNames(SpanConfig.getGuiFieldsNames());
474 result.setNodeData(spanConfigs);
478 @RequestMapping(value = "/nodeports")
480 public Map<String, Object> getNodePorts() {
481 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
482 .getInstance(ISwitchManager.class, containerName, this);
483 if (switchManager == null)
486 Map<String, Object> nodes = new HashMap<String, Object>();
487 Map<Short, String> port;
489 for (Switch node : switchManager.getNetworkDevices()) {
490 port = new HashMap<Short, String>(); // new port
491 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
493 if (nodeConnectorSet != null)
494 for (NodeConnector nodeConnector : nodeConnectorSet) {
495 String nodeConnectorName = ((Name) switchManager
496 .getNodeConnectorProp(nodeConnector,
497 Name.NamePropName)).getValue();
498 port.put((Short) nodeConnector.getID(), nodeConnectorName
499 + "(" + nodeConnector.getID() + ")");
502 nodes.put(node.getNode().toString(), port);
508 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
510 public StatusJsonBean addSpanPort(
511 @RequestParam("jsonData") String jsonData,
512 HttpServletRequest request) {
513 if (!authorize(UserLevel.NETWORKADMIN, request)) {
514 return unauthorizedMessage();
517 StatusJsonBean resultBean = new StatusJsonBean();
519 Gson gson = new Gson();
520 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
521 .getInstance(ISwitchManager.class, containerName, this);
522 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
523 Status result = switchManager.addSpanConfig(cfgObject);
524 if (result.isSuccess()) {
525 resultBean.setStatus(true);
526 resultBean.setMessage("SPAN Port added successfully");
528 resultBean.setStatus(false);
529 resultBean.setMessage(result.getDescription());
531 } catch (Exception e) {
532 resultBean.setStatus(false);
533 resultBean.setMessage("Error occurred while adding span port. "
539 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
541 public StatusJsonBean deleteSpanPorts(
542 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
543 HttpServletRequest request) {
544 if (!authorize(UserLevel.NETWORKADMIN, request)) {
545 return unauthorizedMessage();
548 StatusJsonBean resultBean = new StatusJsonBean();
550 Gson gson = new Gson();
551 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
552 .getInstance(ISwitchManager.class, containerName, this);
553 String[] spans = spanPortsToDelete.split("###");
554 resultBean.setStatus(true);
555 resultBean.setMessage("SPAN Port(s) deleted successfully");
556 for (String span : spans) {
557 if (!span.isEmpty()) {
558 SpanConfig cfgObject = gson
559 .fromJson(span, SpanConfig.class);
560 Status result = switchManager.removeSpanConfig(cfgObject);
561 if (!result.isSuccess()) {
562 resultBean.setStatus(false);
563 resultBean.setMessage(result.getDescription());
568 } catch (Exception e) {
569 resultBean.setStatus(false);
570 resultBean.setMessage("Error occurred while deleting span port. "
576 private String getNodeDesc(String nodeId) {
577 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
578 .getInstance(ISwitchManager.class, containerName, this);
579 String description = "";
580 if (switchManager != null) {
581 description = switchManager.getNodeDescription(Node
582 .fromString(nodeId));
584 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
589 * Is the operation permitted for the given level
593 private boolean authorize(UserLevel level, HttpServletRequest request) {
594 IUserManager userManager = (IUserManager) ServiceHelper
595 .getGlobalInstance(IUserManager.class, this);
596 if (userManager == null) {
600 String username = request.getUserPrincipal().getName();
601 UserLevel userLevel = userManager.getUserLevel(username);
602 if (userLevel.toNumber() <= level.toNumber()) {
608 private StatusJsonBean unauthorizedMessage() {
609 StatusJsonBean message = new StatusJsonBean();
610 message.setStatus(false);
611 message.setMessage("Operation not authorized");
615 @RequestMapping(value = "login")
616 public String login(final HttpServletRequest request,
617 final HttpServletResponse response) {
618 // response.setHeader("X-Page-Location", "/login");
620 * IUserManager userManager = (IUserManager) ServiceHelper
621 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
622 * null) { return "User Manager is not available"; }
624 * String username = request.getUserPrincipal().getName();
627 * model.addAttribute("username", username); model.addAttribute("role",
628 * userManager.getUserLevel(username).toNumber());
630 return "forward:" + "/";