Merge "Enhancement in switch configuration"
[controller.git] / opendaylight / web / flows / src / main / java / org / opendaylight / controller / flows / web / Flows.java
1 /*
2  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.controller.flows.web;
10
11 import java.util.HashMap;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map;
15 import java.util.Set;
16
17 import javax.servlet.http.HttpServletRequest;
18
19 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
20 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
21 import org.opendaylight.controller.sal.authorization.Privilege;
22 import org.opendaylight.controller.sal.authorization.UserLevel;
23 import org.opendaylight.controller.sal.core.Description;
24 import org.opendaylight.controller.sal.core.Name;
25 import org.opendaylight.controller.sal.core.Node;
26 import org.opendaylight.controller.sal.core.NodeConnector;
27 import org.opendaylight.controller.sal.utils.GlobalConstants;
28 import org.opendaylight.controller.sal.utils.ServiceHelper;
29 import org.opendaylight.controller.sal.utils.Status;
30 import org.opendaylight.controller.sal.utils.StatusCode;
31 import org.opendaylight.controller.switchmanager.ISwitchManager;
32 import org.opendaylight.controller.switchmanager.Switch;
33 import org.opendaylight.controller.switchmanager.SwitchConfig;
34 import org.opendaylight.controller.web.DaylightWebUtil;
35 import org.opendaylight.controller.web.IDaylightWeb;
36 import org.springframework.stereotype.Controller;
37 import org.springframework.web.bind.annotation.PathVariable;
38 import org.springframework.web.bind.annotation.RequestMapping;
39 import org.springframework.web.bind.annotation.RequestMethod;
40 import org.springframework.web.bind.annotation.RequestParam;
41 import org.springframework.web.bind.annotation.ResponseBody;
42
43 import com.google.gson.Gson;
44
45 @Controller
46 @RequestMapping("/")
47 public class Flows implements IDaylightWeb {
48     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
49     private static final String WEB_NAME = "Flows";
50     private static final String WEB_ID = "flows";
51     private static final short WEB_ORDER = 2;
52
53     public Flows() {
54         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
55     }
56
57     @Override
58     public String getWebName() {
59         return WEB_NAME;
60     }
61
62     @Override
63     public String getWebId() {
64         return WEB_ID;
65     }
66
67     @Override
68     public short getWebOrder() {
69         return WEB_ORDER;
70     }
71
72     @Override
73     public boolean isAuthorized(UserLevel userLevel) {
74         return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
75     }
76
77     @RequestMapping(value = "/main")
78     @ResponseBody
79     public Map<String, Object> getFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
80         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
81
82         // Derive the privilege this user has on the current container
83         String userName = request.getUserPrincipal().getName();
84         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
85         if (privilege  == Privilege.NONE) {
86             return null;
87         }
88
89         // fetch frm
90         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
91                 .getInstance(IForwardingRulesManager.class, containerName, this);
92         if (frm == null) {
93             return null;
94         }
95
96         // fetch sm
97         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
98                 .getInstance(ISwitchManager.class, containerName, this);
99         if (switchManager == null) {
100             return null;
101         }
102
103         // get static flow list
104         List<FlowConfig> staticFlowList = frm.getStaticFlows();
105         Set<Map<String, Object>> flowSet = new HashSet<Map<String, Object>>();
106         for (FlowConfig flowConfig : staticFlowList) {
107             Map<String, Object> entry = new HashMap<String, Object>();
108             entry.put("flow", flowConfig);
109             entry.put("name", flowConfig.getName());
110             Node node = flowConfig.getNode();
111             entry.put("node", getNodeDesc(node, switchManager));
112             entry.put("nodeId", node.toString());
113             flowSet.add(entry);
114         }
115
116         Map <String, Object> output = new HashMap<String, Object>(2);
117         output.put("flows", flowSet);
118         output.put("privilege", privilege);
119         return output;
120     }
121
122     @RequestMapping(value = "/node-ports")
123     @ResponseBody
124     public Map<String, Object> getNodePorts(HttpServletRequest request, @RequestParam(required = false) String container) {
125         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
126
127         // Derive the privilege this user has on the current container
128         String userName = request.getUserPrincipal().getName();
129         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
130             return null;
131         }
132
133         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
134                 .getInstance(ISwitchManager.class, containerName, this);
135         if (switchManager == null) {
136             return null;
137         }
138
139         Map<String, Object> nodes = new HashMap<String, Object>();
140         Map<Short, String> port;
141
142         for (Switch node : switchManager.getNetworkDevices()) {
143             port = new HashMap<Short, String>(); // new port
144             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
145
146             if (nodeConnectorSet != null) {
147                 for (NodeConnector nodeConnector : nodeConnectorSet) {
148                     String nodeConnectorName = ((Name) switchManager
149                             .getNodeConnectorProp(nodeConnector,
150                                     Name.NamePropName)).getValue();
151                     port.put((Short) nodeConnector.getID(), nodeConnectorName
152                             + "(" + nodeConnector.getNodeConnectorIDString()
153                             + ")");
154                 }
155             }
156
157             // add ports
158             Map<String, Object> entry = new HashMap<String, Object>();
159             entry.put("ports", port);
160
161             // add name
162             entry.put("name", getNodeDesc(node.getNode(), switchManager));
163
164             // add to the node
165             nodes.put(node.getNode().toString(), entry);
166         }
167
168         return nodes;
169     }
170
171     @RequestMapping(value = "/node-flows")
172     @ResponseBody
173     public Map<String, Object> getNodeFlows(HttpServletRequest request, @RequestParam(required = false) String container) {
174         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
175
176         // Derive the privilege this user has on the current container
177         String userName = request.getUserPrincipal().getName();
178         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) == Privilege.NONE) {
179             return null;
180         }
181
182         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
183                 .getInstance(ISwitchManager.class, containerName, this);
184         if (switchManager == null) {
185             return null;
186         }
187         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
188                 .getInstance(IForwardingRulesManager.class, containerName, this);
189         if (frm == null) {
190             return null;
191         }
192
193         Map<String, Object> nodes = new HashMap<String, Object>();
194
195         for (Switch sw : switchManager.getNetworkDevices()) {
196             Node node = sw.getNode();
197
198             List<FlowConfig> flows = frm.getStaticFlows(node);
199
200             String nodeDesc = node.toString();
201             SwitchConfig config = switchManager.getSwitchConfig(node
202                     .toString());
203             if ((config != null) && (config.getProperty(Description.propertyName) != null)) {
204                 nodeDesc = ((Description) config.getProperty(Description.propertyName)).getValue();
205             }
206
207             nodes.put(nodeDesc, flows.size());
208         }
209
210         return nodes;
211     }
212
213     @RequestMapping(value = "/flow", method = RequestMethod.POST)
214     @ResponseBody
215     public String actionFlow(@RequestParam(required = true) String action,
216             @RequestParam(required = false) String body,
217             @RequestParam(required = true) String nodeId,
218             HttpServletRequest request, @RequestParam(required = false) String container) {
219         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
220
221         // Authorization check
222         String userName = request.getUserPrincipal().getName();
223         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
224             return "Operation not authorized";
225         }
226
227         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
228                 .getInstance(IForwardingRulesManager.class, containerName, this);
229         if (frm == null) {
230             return null;
231         }
232
233         Gson gson = new Gson();
234         FlowConfig flow = gson.fromJson(body, FlowConfig.class);
235         Node node = Node.fromString(nodeId);
236         flow.setNode(node);
237         Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
238         if (action.equals("add")) {
239             result = frm.addStaticFlow(flow);
240         }
241
242         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
243                 .getDescription();
244     }
245
246     @RequestMapping(value = "/flow/{nodeId}/{name:.*}", method = RequestMethod.POST)
247     @ResponseBody
248     public String removeFlow(@PathVariable("nodeId") String nodeId,
249             @PathVariable("name") String name,
250             @RequestParam(required = true) String action,
251             HttpServletRequest request, @RequestParam(required = false) String container) {
252         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
253
254         // Authorization check
255         String userName = request.getUserPrincipal().getName();
256         if (DaylightWebUtil.getContainerPrivilege(userName, containerName, this) != Privilege.WRITE) {
257             return "Operation not authorized";
258         }
259
260         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
261                 .getInstance(IForwardingRulesManager.class, containerName, this);
262         if (frm == null) {
263             return null;
264         }
265
266         Status result = null;
267         Node node = Node.fromString(nodeId);
268         if (node == null) {
269             return null;
270         }
271         if (action.equals("remove")) {
272             result = frm.removeStaticFlow(name, node);
273         } else if (action.equals("toggle")) {
274             result = frm.toggleStaticFlowStatus(name, node);
275         } else {
276             result = new Status(StatusCode.BADREQUEST, "Unknown action");
277         }
278
279         return (result.isSuccess()) ? StatusCode.SUCCESS.toString() : result
280                 .getDescription();
281     }
282
283     private String getNodeDesc(Node node, ISwitchManager switchManager) {
284         Description desc = (Description) switchManager.getNodeProp(node, Description.propertyName);
285         String description = (desc == null) ? "" : desc.getValue();
286         return (description.isEmpty() || description.equalsIgnoreCase("none")) ? node.toString() : description;
287     }
288
289 }