d75d14c623da8bb8c4d1331415f6988a2d8c35af
[controller.git] / opendaylight / web / flows / src / main / java / org / opendaylight / controller / flows / web / Flows.java
1
2 /*
3  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
4  *
5  * This program and the accompanying materials are made available under the
6  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7  * and is available at http://www.eclipse.org/legal/epl-v10.html
8  */
9
10 package org.opendaylight.controller.flows.web;
11
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Map;
16 import java.util.Set;
17
18 import org.opendaylight.controller.forwardingrulesmanager.FlowConfig;
19 import org.opendaylight.controller.forwardingrulesmanager.IForwardingRulesManager;
20 import org.opendaylight.controller.sal.authorization.UserLevel;
21 import org.opendaylight.controller.sal.core.Name;
22 import org.opendaylight.controller.sal.core.Node;
23 import org.opendaylight.controller.sal.core.NodeConnector;
24 import org.opendaylight.controller.sal.utils.GlobalConstants;
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.IOneWeb;
33 import org.springframework.security.core.context.SecurityContextHolder;
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 IOneWeb {
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(IOneWeb.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) { return null; }
83
84         // fetch sm
85         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
86                 .getInstance(ISwitchManager.class, containerName, this);
87         if (switchManager == null) { return null; }
88         
89         // get static flow list
90         List<FlowConfig> staticFlowList = frm.getStaticFlows();
91         Set<Map<String, Object>> output = new HashSet<Map<String, Object>>();
92         for (FlowConfig flowConfig : staticFlowList) {
93                 Map<String, Object> entry = new HashMap<String, Object>();
94                 entry.put("flow", flowConfig);
95                 entry.put("name", flowConfig.getName());
96                 Node node = flowConfig.getNode();
97                 String description = switchManager.getNodeDescription(node);
98                 entry.put("node", 
99                                 (description.isEmpty() || 
100                                                 description.equalsIgnoreCase("none"))? 
101                                                                 node.toString() : description);
102                 entry.put("nodeId", node.toString());
103                 output.add(entry);
104         }
105         
106         return output;
107     }
108
109     @RequestMapping(value = "/node-ports")
110     @ResponseBody
111     public Map<String, Object> getNodePorts() {
112         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
113                 .getInstance(ISwitchManager.class, containerName, this);
114         if (switchManager == null) { return null; }
115
116         Map<String, Object> nodes = new HashMap<String, Object>();
117         Map<Short, String> port;
118
119         for (Switch node : switchManager.getNetworkDevices()) {
120             port = new HashMap<Short, String>(); // new port
121             Set<NodeConnector> nodeConnectorSet = node.getNodeConnectors();
122
123             if (nodeConnectorSet != null) {
124                 for (NodeConnector nodeConnector : nodeConnectorSet) {
125                     String nodeConnectorName = ((Name) switchManager
126                             .getNodeConnectorProp(nodeConnector,
127                                     Name.NamePropName)).getValue();
128                     port.put((Short) nodeConnector.getID(),
129                              nodeConnectorName + "("
130                              + nodeConnector.getNodeConnectorIDString() + ")");
131                 }
132             }
133             
134             // add ports
135             Map<String, Object> entry = new HashMap<String, Object>();
136             entry.put("ports", port);
137             
138             // add name
139             String description = switchManager
140                         .getNodeDescription(node.getNode());
141             entry.put("name", (description.isEmpty() || 
142                         description.equalsIgnoreCase("none"))? 
143                         node.getNode().toString() : description);
144             
145             // add to the node
146             nodes.put(node.getNode().toString(), entry);
147         }
148
149         return nodes;
150     }
151     
152     @RequestMapping(value = "/node-flows")
153     @ResponseBody
154     public Map<String, Object> getNodeFlows() {
155         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
156                 .getInstance(ISwitchManager.class, containerName, this);
157         if (switchManager == null) { return null; }
158         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
159                 .getInstance(IForwardingRulesManager.class, "default", this);
160         if (frm == null) { return null; }
161
162         Map<String, Object> nodes = new HashMap<String, Object>();
163
164         for (Switch sw : switchManager.getNetworkDevices()) {
165             Node node = sw.getNode();
166             
167             List<FlowConfig> flows = frm.getStaticFlows(node);
168             
169             String nodeDesc = node.toString();
170             SwitchConfig config = switchManager.getSwitchConfig(node.getNodeIDString());
171             if (config != null) {
172                 nodeDesc = config.getNodeDescription();
173             }
174             
175             nodes.put(nodeDesc, flows.size());
176         }
177
178         return nodes;
179     }
180
181     @RequestMapping(value = "/flow", method = RequestMethod.POST)
182     @ResponseBody
183     public String actionFlow(@RequestParam(required = true) String action,
184             @RequestParam(required = false) String body, @RequestParam(required = true) String nodeId) {
185         if (!isUserAuthorized(UserLevel.NETWORKADMIN)) {
186                 return "Operation not authorized";
187         }
188         
189         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
190                 .getInstance(IForwardingRulesManager.class, containerName, this);
191         if (frm == null) { return null; }
192
193         Gson gson = new Gson();
194         FlowConfig flow = gson.fromJson(body, FlowConfig.class);
195         Node node = Node.fromString(nodeId);
196         flow.setNode(node);
197         Status result = new Status(StatusCode.BADREQUEST, "Invalid request");
198         if (action.equals("add")) {
199             result = frm.addStaticFlow(flow, false);
200         }
201
202         return (result.isSuccess())? StatusCode.SUCCESS.toString(): result.getDescription();
203     }
204     
205     @RequestMapping(value = "/flow/{nodeId}/{name}", method = RequestMethod.POST)
206     @ResponseBody
207     public String removeFlow(@PathVariable("nodeId") String nodeId, @PathVariable("name") String name,
208                 @RequestParam(required = true) String action) {
209         if (!isUserAuthorized(UserLevel.NETWORKADMIN)) { return "Operation not authorized"; }
210         
211         IForwardingRulesManager frm = (IForwardingRulesManager) ServiceHelper
212                 .getInstance(IForwardingRulesManager.class, containerName, this);
213         if (frm == null) { return null; }
214         
215         Status result = null;
216         Node node = Node.fromString(nodeId);
217         if (node == null) { return null; }
218         if (action.equals("remove")) {
219                 result = frm.removeStaticFlow(name, node);
220         } else if (action.equals("toggle")) {
221                 result = frm.toggleStaticFlowStatus(name, node);
222         } else {
223                 result = new Status(StatusCode.BADREQUEST, "Unknown action");
224         }
225         
226         return (result.isSuccess())? StatusCode.SUCCESS.toString(): result.getDescription();
227     }
228     
229     /**
230      * Returns whether the current user's level is same or above
231      * the required authorization level. 
232      * 
233      * @param requiredLevel the authorization level required
234      */
235     private boolean isUserAuthorized(UserLevel requiredLevel) {
236         IUserManager userManager = (IUserManager) ServiceHelper
237                 .getGlobalInstance(IUserManager.class, this);
238         if (userManager == null) { return false; }
239         
240         String username = SecurityContextHolder.getContext().getAuthentication().getName();
241         UserLevel userLevel = userManager.getUserLevel(username);
242         return (userLevel.ordinal() <= requiredLevel.ordinal());
243     }
244
245 }