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