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.flows.web;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
18 import javax.servlet.http.HttpServletRequest;
20 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
21 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
22 import org.opendaylight.controller.sal.authorization.Privilege;
23 import org.opendaylight.controller.sal.authorization.UserLevel;
24 import org.opendaylight.controller.sal.core.Description;
25 import org.opendaylight.controller.sal.core.Name;
26 import org.opendaylight.controller.sal.core.Node;
27 import org.opendaylight.controller.sal.core.NodeConnector;
28 import org.opendaylight.controller.sal.utils.GlobalConstants;
29 import org.opendaylight.controller.sal.utils.ServiceHelper;
30 import org.opendaylight.controller.sal.utils.Status;
31 import org.opendaylight.controller.sal.utils.StatusCode;
32 import org.opendaylight.controller.switchmanager.ISwitchManager;
33 import org.opendaylight.controller.switchmanager.Switch;
34 import org.opendaylight.controller.switchmanager.SwitchConfig;
35 import org.opendaylight.controller.web.DaylightWebUtil;
36 import org.opendaylight.controller.web.IDaylightWeb;
37 import org.springframework.stereotype.Controller;
38 import org.springframework.web.bind.annotation.PathVariable;
39 import org.springframework.web.bind.annotation.RequestMapping;
40 import org.springframework.web.bind.annotation.RequestMethod;
41 import org.springframework.web.bind.annotation.RequestParam;
42 import org.springframework.web.bind.annotation.ResponseBody;
44 import com.google.gson.Gson;
48 public class Flows implements IDaylightWeb {
49 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
50 private static final String WEB_NAME = "Flows";
52 private static final String WEB_ID = "flows";
53 private static final short WEB_ORDER = 2;
55 private final Gson gson;
58 ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
63 public String getWebName() {
68 public String getWebId() {
73 public short getWebOrder() {
78 public boolean isAuthorized(UserLevel userLevel) {
79 return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
82 @RequestMapping(value = "/main")
84 public Map<String, Object> getFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
85 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
87 // Derive the privilege this user has on the current container
88 String userName = request.getUserPrincipal().getName();
89 Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
90 if (privilege == Privilege.NONE) {
95 IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
96 IForwardingRulesManager.class, containerName, this);
102 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
104 if (switchManager == null) {
108 // get static flow list
109 List<FlowConfig> staticFlowList = frm.getStaticFlows();
110 Set<Map<String, Object>> flowSet = new HashSet<Map<String, Object>>();
111 for (FlowConfig flowConfig : staticFlowList) {
112 Map<String, Object> entry = new HashMap<String, Object>();
113 entry.put("flow", flowConfig);
114 entry.put("name", flowConfig.getName());
115 Node node = flowConfig.getNode();
116 entry.put("node", getNodeDesc(node, switchManager));
117 entry.put("nodeId", node.toString());
121 Map<String, Object> output = new HashMap<String, Object>(2);
122 output.put("flows", flowSet);
123 output.put("privilege", privilege);
127 @RequestMapping(value = "/node-ports")
129 public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
130 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
132 // Derive the privilege this user has on the current container
133 String userName = request.getUserPrincipal().getName();
134 if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
138 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
140 if (switchManager == null) {
144 Map<String, Object> nodes = new HashMap<String, Object>();
145 Map<String, String> port;
147 for (Switch node : switchManager.getNetworkDevices()) {
148 port = new HashMap<String, String>(); // new port
149 Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
151 if (nodeConnectorSet != null) {
152 for (NodeConnector nodeConnector : nodeConnectorSet) {
153 String nodeConnectorName = ((Name) switchManager.getNodeConnectorProp(nodeConnector,
154 Name.NamePropName)).getValue();
155 port.put( nodeConnector.getID().toString(),
156 nodeConnectorName + "(" + nodeConnector.getNodeConnectorIDString() + ")");
161 Map<String, Object> entry = new HashMap<String, Object>();
162 entry.put("ports", port);
165 entry.put("name", getNodeDesc(node.getNode(), switchManager));
168 nodes.put(node.getNode().toString(), entry);
174 @RequestMapping(value = "/node-flows")
176 public Map<String, Object> getNodeFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
177 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
179 // Derive the privilege this user has on the current container
180 String userName = request.getUserPrincipal().getName();
181 if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
185 ISwitchManager switchManager = (ISwitchManager) ServiceHelper.getInstance(ISwitchManager.class, containerName,
187 if (switchManager == null) {
190 IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
191 IForwardingRulesManager.class, containerName, this);
196 Map<String, Object> nodes = new HashMap<String, Object>();
198 for (Switch sw : switchManager.getNetworkDevices()) {
199 Node node = sw.getNode();
201 List<FlowConfig> flows = frm.getStaticFlows(node);
203 String nodeDesc = node.toString();
204 SwitchConfig config = switchManager.getSwitchConfig(node.toString());
205 if ((config != null) && (config.getProperty(Description.propertyName) != null)) {
206 nodeDesc = ((Description) config.getProperty(Description.propertyName)).getValue();
209 nodes.put(nodeDesc, flows.size());
216 @RequestMapping(value = "/flow", method = RequestMethod.POST)
218 public String actionFlow(@RequestParam(required = true) String action, @RequestParam(required = false) String body,
219 @RequestParam(required = true) String nodeId, HttpServletRequest request,
220 @RequestParam(required = false) String container) {
221 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
223 // Authorization check
224 String userName = request.getUserPrincipal().getName();
225 if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
226 return "Operation not authorized";
229 IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
230 IForwardingRulesManager.class, containerName, this);
235 FlowConfig flow = gson.fromJson(body, FlowConfig.class);
237 Node node = Node.fromString(nodeId);
240 Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
241 if (action.equals("add")) {
242 result = frm.addStaticFlow(flow);
243 if (result.isSuccess()) {
244 DaylightWebUtil.auditlog("Flow Entry", userName, "added", flow.getName() + " on Node "
245 + DaylightWebUtil.getNodeDesc(node, containerName, this), containerName);
247 } else if (action.equals("edit")){
248 result = frm.modifyStaticFlow(flow);
249 if (result.isSuccess()) {
250 DaylightWebUtil.auditlog("Flow Entry", userName, "updated", flow.getName() + " on Node "
251 + DaylightWebUtil.getNodeDesc(node, containerName, this), containerName);
255 return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result.getDescription();
258 @RequestMapping(value = "/flow/{nodeId}/{name:.*}", method = RequestMethod.POST)
260 public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
261 @RequestParam(required = true) String action, HttpServletRequest request,
262 @RequestParam(required = false) String container) {
263 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
265 // Authorization check
266 String userName = request.getUserPrincipal().getName();
267 if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
268 return "Operation not authorized";
271 IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
272 IForwardingRulesManager.class, containerName, this);
277 Status result = null;
278 Node node = Node.fromString(nodeId);
282 if (action.equals("remove")) {
283 result = frm.removeStaticFlow(name, node);
284 if (result.isSuccess()) {
285 DaylightWebUtil.auditlog("Flow Entry", userName, "removed",
286 name + " on Node " + DaylightWebUtil.getNodeDesc(node, containerName, this), containerName);
288 } else if (action.equals("toggle")) {
289 result = frm.toggleStaticFlowStatus(name, node);
290 if (result.isSuccess()) {
291 DaylightWebUtil.auditlog("Flow Entry", userName, "toggled",
292 name + " on Node " + DaylightWebUtil.getNodeDesc(node, containerName, this), containerName);
295 result = new Status(StatusCode.BADREQUEST, "Unknown action");
298 return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result.getDescription();
301 @SuppressWarnings("unchecked")
302 @RequestMapping(value = "/flow/deleteFlows", method = RequestMethod.POST)
304 public String removeSelectedFlows(@RequestParam(required = false) String body, HttpServletRequest request,
305 @RequestParam(required = false) String container) {
306 String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
308 // Authorization check
309 String userName = request.getUserPrincipal().getName();
310 if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
311 return "Operation not authorized";
313 IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper.getInstance(
314 IForwardingRulesManager.class, containerName, this);
316 return "Forwarding Rules Manager is not available";
319 List<Map<String, String>> flowList = new ArrayList<Map<String, String>>();
320 flowList = gson.fromJson(body, flowList.getClass());
321 Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
323 for (Map<String, String> flowEntry : flowList) {
324 Node node = Node.fromString(flowEntry.get("node"));
325 result = frm.removeStaticFlow(flowEntry.get("name"), node);
326 if (result.isSuccess()) {
327 DaylightWebUtil.auditlog("Flow Entry", userName, "removed", flowEntry.get("name") + " on Node "
328 + DaylightWebUtil.getNodeDesc(node, containerName, this), containerName);
330 status = flowEntry.get("name") + ", " + status;
333 if (!status.equals("")) {
334 return "Could not remove " + status.substring(0, status.length() - 2) + " Flow(s)";
340 private String getNodeDesc(Node node, ISwitchManager switchManager) {
341 Description desc = (Description) switchManager.getNodeProp(node, Description.propertyName);
342 String description = (desc == null) ? "" : desc.getValue();
343 return (description.isEmpty() || description.equalsIgnoreCase("none")) ? node.toString() : description;