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