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