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.Name;
34 import org.opendaylight.controller.sal.core.Node;
35 import org.opendaylight.controller.sal.core.NodeConnector;
36 import org.opendaylight.controller.sal.core.Tier;
37 import org.opendaylight.controller.sal.utils.GlobalConstants;
38 import org.opendaylight.controller.sal.utils.HexEncode;
39 import org.opendaylight.controller.sal.utils.ServiceHelper;
40 import org.opendaylight.controller.sal.utils.Status;
41 import org.opendaylight.controller.sal.utils.TierHelper;
42 import org.opendaylight.controller.switchmanager.ISwitchManager;
43 import org.opendaylight.controller.switchmanager.SpanConfig;
44 import org.opendaylight.controller.switchmanager.SubnetConfig;
45 import org.opendaylight.controller.switchmanager.Switch;
46 import org.opendaylight.controller.switchmanager.SwitchConfig;
48 import com.google.gson.Gson;
52 public class Devices implements IDaylightWeb {
53 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
54 private final String WEB_NAME = "Devices";
55 private final String WEB_ID = "devices";
56 private final short WEB_ORDER = 1;
57 private final String containerName = GlobalConstants.DEFAULT.toString();
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() {
86 Gson gson = new Gson();
87 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
88 .getInstance(ISwitchManager.class, containerName, this);
89 List<Map<String, String>> nodeData = new ArrayList<Map<String, String>>();
90 for (Switch device : switchManager.getNetworkDevices()) {
91 HashMap<String, String> nodeDatum = new HashMap<String, String>();
92 Node node = device.getNode();
93 Tier tier = (Tier) switchManager.getNodeProp(node,
96 nodeDatum.put("containerName", containerName);
97 nodeDatum.put("nodeName", switchManager.getNodeDescription(node));
98 nodeDatum.put("nodeId", node.toString());//.getNodeIDString());
99 int tierNumber = (tier == null) ? TierHelper.unknownTierNumber
101 nodeDatum.put("tierName", TierHelper.getTierName(tierNumber)
102 + " (Tier-" + tierNumber + ")");
103 nodeDatum.put("tier", tierNumber + "");
104 SwitchConfig sc = switchManager.getSwitchConfig(device.getNode()
106 String modeStr = (sc != null) ? sc.getMode() : "0";
107 nodeDatum.put("mode", modeStr);
109 nodeDatum.put("json", gson.toJson(nodeDatum));
111 HexEncode.bytesToHexString(device.getDataLayerAddress()));
112 StringBuffer sb1 = new StringBuffer();
113 Set<NodeConnector> nodeConnectorSet = device.getNodeConnectors();
114 String nodeConnectorName;
115 String nodeConnectorNumberToStr;
116 if (nodeConnectorSet != null && nodeConnectorSet.size() > 0) {
117 Map<Short, String> portList = new HashMap<Short, String>();
118 for (NodeConnector nodeConnector : nodeConnectorSet) {
119 nodeConnectorNumberToStr = nodeConnector.getID().toString();
120 Name ncName = ((Name) switchManager.getNodeConnectorProp(
121 nodeConnector, Name.NamePropName));
122 nodeConnectorName = (ncName != null) ? ncName.getValue()
124 portList.put(Short.parseShort(nodeConnectorNumberToStr),
127 Map<Short, String> sortedPortList = new TreeMap<Short, String>(
129 for (Entry<Short, String> e : sortedPortList.entrySet()) {
130 sb1.append(e.getValue() + "(" + e.getKey() + ")");
134 nodeDatum.put("ports", sb1.toString());
135 nodeData.add(nodeDatum);
137 DevicesJsonBean result = new DevicesJsonBean();
138 result.setNodeData(nodeData);
139 List<String> columnNames = new ArrayList<String>();
140 columnNames.add("Node ID");
141 columnNames.add("Node Name");
142 columnNames.add("Tier");
143 columnNames.add("Mac Address");
144 columnNames.add("Ports");
146 result.setColumnNames(columnNames);
150 @RequestMapping(value = "/tiers", method = RequestMethod.GET)
152 public List<String> getTiers() {
153 return TierHelper.getTiers();
156 @RequestMapping(value = "/nodesLearnt/update", method = RequestMethod.GET)
158 public StatusJsonBean updateLearntNode(
159 @RequestParam("nodeName") String nodeName,
160 @RequestParam("nodeId") String nodeId,
161 @RequestParam("tier") String tier,
162 @RequestParam("operationMode") String operationMode,
163 HttpServletRequest request) {
164 if (!authorize(UserLevel.NETWORKADMIN, request)) {
165 return unauthorizedMessage();
168 StatusJsonBean resultBean = new StatusJsonBean();
170 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
171 .getInstance(ISwitchManager.class, containerName, this);
172 SwitchConfig cfg = new SwitchConfig(nodeId, nodeName, tier,
174 switchManager.updateSwitchConfig(cfg);
175 resultBean.setStatus(true);
176 resultBean.setMessage("Updated node information successfully");
177 } catch (Exception e) {
178 resultBean.setStatus(false);
179 resultBean.setMessage("Error updating node information. "
185 @RequestMapping(value = "/staticRoutes", method = RequestMethod.GET)
187 public DevicesJsonBean getStaticRoutes() {
188 Gson gson = new Gson();
189 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
190 .getInstance(IForwardingStaticRouting.class, containerName,
192 List<Map<String, String>> staticRoutes = new ArrayList<Map<String, String>>();
193 ConcurrentMap<String, StaticRouteConfig> routeConfigs = staticRouting
194 .getStaticRouteConfigs();
195 if (routeConfigs == null) {
198 for (StaticRouteConfig conf : routeConfigs.values()) {
199 Map<String, String> staticRoute = new HashMap<String, String>();
200 staticRoute.put("name", conf.getName());
201 staticRoute.put("staticRoute", conf.getStaticRoute());
202 staticRoute.put("nextHopType", conf.getNextHopType());
203 staticRoute.put("nextHop", conf.getNextHop());
204 staticRoute.put("json", gson.toJson(conf));
205 staticRoutes.add(staticRoute);
207 DevicesJsonBean result = new DevicesJsonBean();
208 result.setColumnNames(StaticRouteConfig.getGuiFieldsNames());
209 result.setNodeData(staticRoutes);
213 @RequestMapping(value = "/staticRoute/add", method = RequestMethod.GET)
215 public StatusJsonBean addStaticRoute(
216 @RequestParam("routeName") String routeName,
217 @RequestParam("staticRoute") String staticRoute,
218 @RequestParam("nextHop") String nextHop, HttpServletRequest request) {
219 if (!authorize(UserLevel.NETWORKADMIN, request)) {
220 return unauthorizedMessage();
223 StatusJsonBean result = new StatusJsonBean();
225 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
226 .getInstance(IForwardingStaticRouting.class, containerName,
228 StaticRouteConfig config = new StaticRouteConfig();
229 config.setName(routeName);
230 config.setStaticRoute(staticRoute);
231 config.setNextHop(nextHop);
232 Status addStaticRouteResult = staticRouting.addStaticRoute(config);
233 if (addStaticRouteResult.isSuccess()) {
234 result.setStatus(true);
235 result.setMessage("Static Route saved successfully");
237 result.setStatus(false);
238 result.setMessage(addStaticRouteResult.getDescription());
240 } catch (Exception e) {
241 result.setStatus(false);
242 result.setMessage("Error - " + e.getMessage());
247 @RequestMapping(value = "/staticRoute/delete", method = RequestMethod.GET)
249 public StatusJsonBean deleteStaticRoute(
250 @RequestParam("routesToDelete") String routesToDelete,
251 HttpServletRequest request) {
252 if (!authorize(UserLevel.NETWORKADMIN, request)) {
253 return unauthorizedMessage();
256 StatusJsonBean resultBean = new StatusJsonBean();
258 IForwardingStaticRouting staticRouting = (IForwardingStaticRouting) ServiceHelper
259 .getInstance(IForwardingStaticRouting.class, containerName,
261 String[] routes = routesToDelete.split(",");
263 resultBean.setStatus(true);
265 .setMessage("Successfully deleted selected static routes");
266 for (String route : routes) {
267 result = staticRouting.removeStaticRoute(route);
268 if (!result.isSuccess()) {
269 resultBean.setStatus(false);
270 resultBean.setMessage(result.getDescription());
274 } catch (Exception e) {
275 resultBean.setStatus(false);
277 .setMessage("Error occurred while deleting static routes. "
283 @RequestMapping(value = "/subnets", method = RequestMethod.GET)
285 public DevicesJsonBean getSubnetGateways() {
286 Gson gson = new Gson();
287 List<Map<String, String>> subnets = new ArrayList<Map<String, String>>();
288 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
289 .getInstance(ISwitchManager.class, containerName, this);
290 for (SubnetConfig conf : switchManager.getSubnetsConfigList()) {
291 Map<String, String> subnet = new HashMap<String, String>();
292 subnet.put("name", conf.getName());
293 subnet.put("subnet", conf.getSubnet());
294 subnet.put("json", gson.toJson(conf));
297 DevicesJsonBean result = new DevicesJsonBean();
298 result.setColumnNames(SubnetConfig.getGuiFieldsNames());
299 result.setNodeData(subnets);
303 @RequestMapping(value = "/subnetGateway/add", method = RequestMethod.GET)
305 public StatusJsonBean addSubnetGateways(
306 @RequestParam("gatewayName") String gatewayName,
307 @RequestParam("gatewayIPAddress") String gatewayIPAddress,
308 HttpServletRequest request) {
309 if (!authorize(UserLevel.NETWORKADMIN, request)) {
310 return unauthorizedMessage();
313 StatusJsonBean resultBean = new StatusJsonBean();
315 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
316 .getInstance(ISwitchManager.class, containerName, this);
317 SubnetConfig cfgObject = new SubnetConfig(gatewayName,
318 gatewayIPAddress, new ArrayList<String>());
319 Status result = switchManager.addSubnet(cfgObject);
320 if (result.isSuccess()) {
321 resultBean.setStatus(true);
322 resultBean.setMessage("Added gateway address successfully");
324 resultBean.setStatus(false);
325 resultBean.setMessage(result.getDescription());
327 } catch (Exception e) {
328 resultBean.setStatus(false);
329 resultBean.setMessage(e.getMessage());
334 @RequestMapping(value = "/subnetGateway/delete", method = RequestMethod.GET)
336 public StatusJsonBean deleteSubnetGateways(
337 @RequestParam("gatewaysToDelete") String gatewaysToDelete,
338 HttpServletRequest request) {
339 if (!authorize(UserLevel.NETWORKADMIN, request)) {
340 return unauthorizedMessage();
343 StatusJsonBean resultBean = new StatusJsonBean();
345 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
346 .getInstance(ISwitchManager.class, containerName, this);
347 String[] subnets = gatewaysToDelete.split(",");
348 resultBean.setStatus(true);
349 resultBean.setMessage("Added gateway address successfully");
350 for (String subnet : subnets) {
351 Status result = switchManager.removeSubnet(subnet);
352 if (!result.isSuccess()) {
353 resultBean.setStatus(false);
354 resultBean.setMessage(result.getDescription());
358 } catch (Exception e) {
359 resultBean.setStatus(false);
360 resultBean.setMessage(e.getMessage());
365 @RequestMapping(value = "/subnetGateway/ports/add", method = RequestMethod.GET)
367 public StatusJsonBean addSubnetGatewayPort(
368 @RequestParam("portsName") String portsName,
369 @RequestParam("ports") String ports,
370 @RequestParam("nodeId") String nodeId, HttpServletRequest request) {
371 if (!authorize(UserLevel.NETWORKADMIN, request)) {
372 return unauthorizedMessage();
375 StatusJsonBean resultBean = new StatusJsonBean();
377 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
378 .getInstance(ISwitchManager.class, containerName, this);
379 Status result = switchManager.addPortsToSubnet(portsName, nodeId
382 if (result.isSuccess()) {
383 resultBean.setStatus(true);
385 .setMessage("Added ports to subnet gateway address successfully");
387 resultBean.setStatus(false);
388 resultBean.setMessage(result.getDescription());
390 } catch (Exception e) {
391 resultBean.setStatus(false);
392 resultBean.setMessage(e.getMessage());
397 @RequestMapping(value = "/subnetGateway/ports/delete", method = RequestMethod.GET)
399 public StatusJsonBean deleteSubnetGatewayPort(
400 @RequestParam("gatewayName") String gatewayName,
401 @RequestParam("nodePort") String nodePort,
402 HttpServletRequest request) {
403 if (!authorize(UserLevel.NETWORKADMIN, request)) {
404 return unauthorizedMessage();
407 StatusJsonBean resultBean = new StatusJsonBean();
409 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
410 .getInstance(ISwitchManager.class, containerName, this);
411 Status result = switchManager.removePortsFromSubnet(gatewayName,
414 if (result.isSuccess()) {
415 resultBean.setStatus(true);
417 .setMessage("Deleted port from subnet gateway address successfully");
419 resultBean.setStatus(false);
420 resultBean.setMessage(result.getDescription());
422 } catch (Exception e) {
423 resultBean.setStatus(false);
424 resultBean.setMessage(e.getMessage());
429 @RequestMapping(value = "/spanPorts", method = RequestMethod.GET)
431 public DevicesJsonBean getSpanPorts() {
432 Gson gson = new Gson();
433 List<String> spanConfigs_json = new ArrayList<String>();
434 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
435 .getInstance(ISwitchManager.class, containerName, this);
436 for (SpanConfig conf : switchManager.getSpanConfigList()) {
437 spanConfigs_json.add(gson.toJson(conf));
439 ObjectMapper mapper = new ObjectMapper();
440 List<Map<String, String>> spanConfigs = new ArrayList<Map<String, String>>();
441 for (String config_json : spanConfigs_json) {
443 @SuppressWarnings("unchecked")
444 Map<String, String> config_data = mapper.readValue(config_json,
446 Map<String, String> config = new HashMap<String, String>();
447 for (String name : config_data.keySet()) {
448 config.put(name, config_data.get(name));
449 // Add switch name value (non-configuration field)
450 config.put("nodeName",
451 getNodeDesc(config_data.get("nodeId")));
453 config.put("json", config_json);
454 spanConfigs.add(config);
455 } catch (Exception e) {
456 // TODO: Handle the exception.
459 DevicesJsonBean result = new DevicesJsonBean();
460 result.setColumnNames(SpanConfig.getGuiFieldsNames());
461 result.setNodeData(spanConfigs);
465 @RequestMapping(value = "/nodeports")
467 public Map<String, Object> getNodePorts() {
468 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
469 .getInstance(ISwitchManager.class, containerName, this);
470 if (switchManager == null)
473 Map<String, Object> nodes = new HashMap<String, Object>();
474 Map<Short, String> port;
476 for (Switch node : switchManager.getNetworkDevices()) {
477 port = new HashMap<Short, String>(); // new port
478 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
480 if (nodeConnectorSet != null)
481 for (NodeConnector nodeConnector : nodeConnectorSet) {
482 String nodeConnectorName = ((Name) switchManager
483 .getNodeConnectorProp(nodeConnector,
484 Name.NamePropName)).getValue();
485 port.put((Short) nodeConnector.getID(), nodeConnectorName
486 + "(" + nodeConnector.getID() + ")");
489 nodes.put(node.getNode().toString(), port);
495 @RequestMapping(value = "/spanPorts/add", method = RequestMethod.GET)
497 public StatusJsonBean addSpanPort(
498 @RequestParam("jsonData") String jsonData,
499 HttpServletRequest request) {
500 if (!authorize(UserLevel.NETWORKADMIN, request)) {
501 return unauthorizedMessage();
504 StatusJsonBean resultBean = new StatusJsonBean();
506 Gson gson = new Gson();
507 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
508 .getInstance(ISwitchManager.class, containerName, this);
509 SpanConfig cfgObject = gson.fromJson(jsonData, SpanConfig.class);
510 Status result = switchManager.addSpanConfig(cfgObject);
511 if (result.isSuccess()) {
512 resultBean.setStatus(true);
513 resultBean.setMessage("SPAN Port added successfully");
515 resultBean.setStatus(false);
516 resultBean.setMessage(result.getDescription());
518 } catch (Exception e) {
519 resultBean.setStatus(false);
520 resultBean.setMessage("Error occurred while adding span port. "
526 @RequestMapping(value = "/spanPorts/delete", method = RequestMethod.GET)
528 public StatusJsonBean deleteSpanPorts(
529 @RequestParam("spanPortsToDelete") String spanPortsToDelete,
530 HttpServletRequest request) {
531 if (!authorize(UserLevel.NETWORKADMIN, request)) {
532 return unauthorizedMessage();
535 StatusJsonBean resultBean = new StatusJsonBean();
537 Gson gson = new Gson();
538 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
539 .getInstance(ISwitchManager.class, containerName, this);
540 String[] spans = spanPortsToDelete.split("###");
541 resultBean.setStatus(true);
542 resultBean.setMessage("SPAN Port(s) deleted successfully");
543 for (String span : spans) {
544 if (!span.isEmpty()) {
545 SpanConfig cfgObject = gson
546 .fromJson(span, SpanConfig.class);
547 Status result = switchManager.removeSpanConfig(cfgObject);
548 if (!result.isSuccess()) {
549 resultBean.setStatus(false);
550 resultBean.setMessage(result.getDescription());
555 } catch (Exception e) {
556 resultBean.setStatus(false);
557 resultBean.setMessage("Error occurred while deleting span port. "
563 private String getNodeDesc(String nodeId) {
564 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
565 .getInstance(ISwitchManager.class, containerName, this);
566 String description = "";
567 if (switchManager != null) {
568 description = switchManager.getNodeDescription(Node
569 .fromString(nodeId));
571 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? nodeId
576 * Is the operation permitted for the given level
580 private boolean authorize(UserLevel level, HttpServletRequest request) {
581 IUserManager userManager = (IUserManager) ServiceHelper
582 .getGlobalInstance(IUserManager.class, this);
583 if (userManager == null) {
587 String username = request.getUserPrincipal().getName();
588 UserLevel userLevel = userManager.getUserLevel(username);
589 if (userLevel.toNumber() <= level.toNumber()) {
595 private StatusJsonBean unauthorizedMessage() {
596 StatusJsonBean message = new StatusJsonBean();
597 message.setStatus(false);
598 message.setMessage("Operation not authorized");
602 @RequestMapping(value = "login")
603 public String login(final HttpServletRequest request,
604 final HttpServletResponse response) {
605 // response.setHeader("X-Page-Location", "/login");
607 * IUserManager userManager = (IUserManager) ServiceHelper
608 * .getGlobalInstance(IUserManager.class, this); if (userManager ==
609 * null) { return "User Manager is not available"; }
611 * String username = request.getUserPrincipal().getName();
614 * model.addAttribute("username", username); model.addAttribute("role",
615 * userManager.getUserLevel(username).toNumber());
617 return "forward:" + "/";