Fix Connection manager to retrieve inventory when is up
[controller.git] / opendaylight / web / troubleshoot / src / main / java / org / opendaylight / controller / troubleshoot / web / Troubleshoot.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.troubleshoot.web;
10
11 import java.net.InetAddress;
12 import java.util.ArrayList;
13 import java.util.Arrays;
14 import java.util.Date;
15 import java.util.HashMap;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import javax.servlet.http.HttpServletRequest;
21
22 import org.opendaylight.controller.sal.action.Action;
23 import org.opendaylight.controller.sal.action.Output;
24 import org.opendaylight.controller.sal.action.SetVlanId;
25 import org.opendaylight.controller.sal.authorization.Privilege;
26 import org.opendaylight.controller.sal.authorization.UserLevel;
27 import org.opendaylight.controller.sal.core.Description;
28 import org.opendaylight.controller.sal.core.Node;
29 import org.opendaylight.controller.sal.core.NodeConnector;
30 import org.opendaylight.controller.sal.core.TimeStamp;
31 import org.opendaylight.controller.sal.flowprogrammer.Flow;
32 import org.opendaylight.controller.sal.match.Match;
33 import org.opendaylight.controller.sal.match.MatchType;
34 import org.opendaylight.controller.sal.reader.FlowOnNode;
35 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
36 import org.opendaylight.controller.sal.utils.EtherTypes;
37 import org.opendaylight.controller.sal.utils.GlobalConstants;
38 import org.opendaylight.controller.sal.utils.HexEncode;
39 import org.opendaylight.controller.sal.utils.IPProtocols;
40 import org.opendaylight.controller.sal.utils.NetUtils;
41 import org.opendaylight.controller.sal.utils.ServiceHelper;
42 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
43 import org.opendaylight.controller.switchmanager.ISwitchManager;
44 import org.opendaylight.controller.web.DaylightWebUtil;
45 import org.opendaylight.controller.web.IDaylightWeb;
46 import org.springframework.stereotype.Controller;
47 import org.springframework.web.bind.annotation.RequestMapping;
48 import org.springframework.web.bind.annotation.RequestMethod;
49 import org.springframework.web.bind.annotation.RequestParam;
50 import org.springframework.web.bind.annotation.ResponseBody;
51
52 @Controller
53 @RequestMapping("/")
54 public class Troubleshoot implements IDaylightWeb {
55     private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
56     private static final List<String> flowStatsColumnNames = Arrays.asList("Node", "In Port",
57             "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
58             "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
59             "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
60             "Priority");
61     private static final List<String> portStatsColumnNames = Arrays.asList("Node Connector",
62             "Rx Pkts", "Tx Pkts", "Rx Bytes", "Tx Bytes", "Rx Drops",
63             "Tx Drops", "Rx Errs", "Tx Errs", "Rx Frame Errs",
64             "Rx OverRun Errs", "Rx CRC Errs", "Collisions");
65     private static final List<String> nodesColumnNames = Arrays.asList("Node", "Node ID", "Statistics");
66     private static final List<String> nodeStatsColumnNames = Arrays.asList("Node", "Node ID", "Statistics");
67     private final String WEB_NAME = "Troubleshoot";
68     private final String WEB_ID = "troubleshoot";
69     private final short WEB_ORDER = 4;
70
71
72     public Troubleshoot() {
73         ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
74     }
75
76     @Override
77     public String getWebName() {
78         return WEB_NAME;
79     }
80
81     @Override
82     public String getWebId() {
83         return WEB_ID;
84     }
85
86     @Override
87     public short getWebOrder() {
88         return WEB_ORDER;
89     }
90
91     @Override
92     public boolean isAuthorized(UserLevel userLevel) {
93         return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
94     }
95
96     @RequestMapping(value = "/existingNodes", method = RequestMethod.GET)
97     @ResponseBody
98     public TroubleshootingJsonBean getExistingNodes(HttpServletRequest request, @RequestParam(required = false) String container) {
99         List<Map<String, String>> lines = new ArrayList<Map<String, String>>();
100         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
101
102         // Derive the privilege this user has on the current container
103         String userName = request.getUserPrincipal().getName();
104         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
105
106         if (privilege != Privilege.NONE) {
107             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
108                     .getInstance(ISwitchManager.class, containerName, this);
109             Set<Node> nodeSet = (switchManager != null) ? switchManager.getNodes() : null;
110             if (nodeSet != null) {
111                 for (Node node : nodeSet) {
112                     Map<String, String> device = new HashMap<String, String>();
113                     device.put("nodeName", getNodeDesc(node, switchManager));
114                     device.put("nodeId", node.toString());
115                     lines.add(device);
116                 }
117             }
118         }
119
120         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
121         result.setColumnNames(nodesColumnNames);
122         result.setNodeData(lines);
123         return result;
124     }
125
126     @RequestMapping(value = "/uptime", method = RequestMethod.GET)
127     @ResponseBody
128     public TroubleshootingJsonBean getUptime(HttpServletRequest request, @RequestParam(required = false) String container) {
129         List<Map<String, String>> lines = new ArrayList<Map<String, String>>();
130         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
131
132         // Derive the privilege this user has on the current container
133         String userName = request.getUserPrincipal().getName();
134         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
135
136         if (privilege != Privilege.NONE) {
137             ISwitchManager switchManager = (ISwitchManager) ServiceHelper
138                     .getInstance(ISwitchManager.class, containerName, this);
139             Set<Node> nodeSet = (switchManager != null) ? switchManager.getNodes() : null;
140             if (nodeSet != null) {
141                 for (Node node : nodeSet) {
142                     Map<String, String> device = new HashMap<String, String>();
143                     device.put("nodeName", getNodeDesc(node, switchManager));
144                     device.put("nodeId", node.toString());
145                     TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
146                             node, TimeStamp.TimeStampPropName);
147                     Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
148                     String date = (time == 0) ? "" : (new Date(time)).toString();
149                     device.put("connectedSince", date);
150                     lines.add(device);
151                 }
152             }
153         }
154
155         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
156         result.setColumnNames(nodeStatsColumnNames);
157         result.setNodeData(lines);
158         return result;
159     }
160
161     @RequestMapping(value = "/flowStats", method = RequestMethod.GET)
162     @ResponseBody
163     public TroubleshootingJsonBean getFlowStats(
164             @RequestParam("nodeId") String nodeId,
165             HttpServletRequest request, @RequestParam(required = false) String container) {
166         List<Map<String, String>> cells = new ArrayList<Map<String, String>>();
167         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
168
169         // Derive the privilege this user has on the current container
170         String userName = request.getUserPrincipal().getName();
171         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
172
173         if (privilege != Privilege.NONE) {
174             IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
175                     .getInstance(IStatisticsManager.class, containerName, this);
176             if (statisticsManager != null) {
177                 Node node = Node.fromString(nodeId);
178                 List<FlowOnNode> statistics = statisticsManager.getFlows(node);
179                 for (FlowOnNode stats : statistics) {
180                     cells.add(this.convertFlowStatistics(node, stats, containerName));
181                 }
182             }
183         }
184
185         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
186         result.setColumnNames(flowStatsColumnNames);
187         result.setNodeData(cells);
188         return result;
189     }
190
191     @RequestMapping(value = "/portStats", method = RequestMethod.GET)
192     @ResponseBody
193     public TroubleshootingJsonBean getPortStats(
194             @RequestParam("nodeId") String nodeId,
195             HttpServletRequest request, @RequestParam(required = false) String container) {
196         List<Map<String, String>> cells = new ArrayList<Map<String, String>>();
197         String containerName = (container == null) ? GlobalConstants.DEFAULT.toString() : container;
198
199         // Derive the privilege this user has on the current container
200         String userName = request.getUserPrincipal().getName();
201         Privilege privilege = DaylightWebUtil.getContainerPrivilege(userName, containerName, this);
202
203         if (privilege != Privilege.NONE) {
204             IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
205                     .getInstance(IStatisticsManager.class, containerName, this);
206             if (statisticsManager != null) {
207                 Node node = Node.fromString(nodeId);
208                 List<NodeConnectorStatistics> statistics = statisticsManager
209                         .getNodeConnectorStatistics(node);
210                 for (NodeConnectorStatistics stats : statistics) {
211                     cells.add(this.convertPortsStatistics(stats));
212                 }
213             }
214         }
215
216         TroubleshootingJsonBean result = new TroubleshootingJsonBean();
217         result.setColumnNames(portStatsColumnNames);
218         result.setNodeData(cells);
219         return result;
220     }
221
222     private Map<String, String> convertPortsStatistics(
223             NodeConnectorStatistics ncStats) {
224         Map<String, String> row = new HashMap<String, String>();
225
226         row.put("nodeConnector",
227                 String.valueOf(ncStats.getNodeConnector().toString()));
228         row.put("rxPkts", String.valueOf(ncStats.getReceivePacketCount()));
229         row.put("txPkts", String.valueOf(ncStats.getTransmitPacketCount()));
230         row.put("rxBytes", String.valueOf(ncStats.getReceiveByteCount()));
231         row.put("txBytes", String.valueOf(ncStats.getTransmitByteCount()));
232         row.put("rxDrops", String.valueOf(ncStats.getReceiveDropCount()));
233         row.put("txDrops", String.valueOf(ncStats.getTransmitDropCount()));
234         row.put("rxErrors", String.valueOf(ncStats.getReceiveErrorCount()));
235         row.put("txErrors", String.valueOf(ncStats.getTransmitErrorCount()));
236         row.put("rxFrameErrors",
237                 String.valueOf(ncStats.getReceiveFrameErrorCount()));
238         row.put("rxOverRunErrors",
239                 String.valueOf(ncStats.getReceiveOverRunErrorCount()));
240         row.put("rxCRCErrors",
241                 String.valueOf(ncStats.getReceiveCRCErrorCount()));
242         row.put("collisions", String.valueOf(ncStats.getCollisionCount()));
243
244         return row;
245     }
246
247     private Map<String, String> convertFlowStatistics(Node node,
248             FlowOnNode flowOnNode,
249             String containerName) {
250         Map<String, String> row = new HashMap<String, String>();
251         Flow flow = flowOnNode.getFlow();
252         Match match = flow.getMatch();
253         ISwitchManager switchManager = (ISwitchManager) ServiceHelper
254                 .getInstance(ISwitchManager.class, containerName, this);
255         String desc = getNodeDesc(node, switchManager);
256         desc = (desc == null || desc.isEmpty() || desc.equalsIgnoreCase("none"))?
257                         node.toString() : desc;
258         row.put("nodeName", desc);
259         if (match.isPresent(MatchType.IN_PORT)) {
260             row.put(MatchType.IN_PORT.id(), ((NodeConnector) flow.getMatch()
261                     .getField(MatchType.IN_PORT).getValue())
262                     .getNodeConnectorIdAsString());
263         } else {
264             row.put(MatchType.IN_PORT.id(), "*");
265         }
266         if (match.isPresent(MatchType.DL_SRC)) {
267             row.put(MatchType.DL_SRC.id(),
268                     (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
269                             .getField(MatchType.DL_SRC).getValue()))));
270         } else {
271             row.put(MatchType.DL_SRC.id(), "*");
272         }
273         if (match.isPresent(MatchType.DL_DST)) {
274             row.put(MatchType.DL_DST.id(),
275                     (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
276                             .getField(MatchType.DL_DST).getValue()))));
277         } else {
278             row.put(MatchType.DL_DST.id(), "*");
279         }
280         if (match.isPresent(MatchType.DL_TYPE)) {
281             row.put(MatchType.DL_TYPE.id(),
282                     EtherTypes.getEtherTypeName(((Short) flow.getMatch()
283                             .getField(MatchType.DL_TYPE).getValue())));
284         } else {
285             row.put(MatchType.DL_TYPE.id(), "*");
286         }
287
288         // Some physical switch has vlan as ffff to show "any" vlan
289         if (match.isPresent(MatchType.DL_VLAN)) {
290             if (((Short) flow.getMatch().getField(MatchType.DL_VLAN).getValue())
291                     .shortValue() < 0) {
292                 row.put(MatchType.DL_VLAN.id(), "0");
293             } else {
294                 row.put(MatchType.DL_VLAN.id(), ((Short) flow.getMatch()
295                         .getField(MatchType.DL_VLAN).getValue()).toString());
296             }
297         } else {
298             row.put(MatchType.DL_VLAN.id(), "*");
299         }
300         if (match.isPresent(MatchType.NW_SRC)) {
301             row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
302                     .getField(MatchType.NW_SRC).getValue()).getHostAddress());
303         } else {
304             row.put(MatchType.NW_SRC.id(), "*");
305         }
306         if (match.isPresent(MatchType.NW_DST)) {
307             row.put(MatchType.NW_DST.id(), ((InetAddress) flow.getMatch()
308                     .getField(MatchType.NW_DST).getValue()).getHostAddress());
309         } else {
310             row.put(MatchType.NW_DST.id(), "*");
311         }
312         if (match.isPresent(MatchType.NW_PROTO)) {
313             row.put(MatchType.NW_PROTO.id(),
314                     IPProtocols.getProtocolName(((Byte) flow.getMatch()
315                             .getField(MatchType.NW_PROTO).getValue())));
316         } else {
317             row.put(MatchType.NW_PROTO.id(), "*");
318         }
319         if (match.isPresent(MatchType.TP_SRC)) {
320             Short tpSrc = (Short) (flow.getMatch().getField(MatchType.TP_SRC)
321                     .getValue());
322             row.put(MatchType.TP_SRC.id(),
323                         String.valueOf(NetUtils.getUnsignedShort(tpSrc)));
324         } else {
325             row.put(MatchType.TP_SRC.id(), "*");
326         }
327         if (match.isPresent(MatchType.TP_DST)) {
328             Short tpDst = (Short) (flow.getMatch().getField(MatchType.TP_DST)
329                     .getValue());
330             row.put(MatchType.TP_DST.id(),
331                         String.valueOf(NetUtils.getUnsignedShort(tpDst)));
332         } else {
333             row.put(MatchType.TP_DST.id(), "*");
334         }
335
336         row.put("byteCount", ((Long) flowOnNode.getByteCount()).toString());
337         row.put("packetCount", ((Long) flowOnNode.getPacketCount()).toString());
338
339         StringBuffer actions = new StringBuffer();
340         StringBuffer outPorts = new StringBuffer();
341         String outVlanId = null;
342         for (Action action : flow.getActions()) {
343             actions.append(action.getType().toString() + "\n");
344             if (action instanceof Output) {
345                 Output ao = (Output) action;
346                 if (outPorts.length() > 0) {
347                     outPorts.append(" ");
348                 }
349                 outPorts.append(ao.getPort().getNodeConnectorIdAsString());
350             } else if (action instanceof SetVlanId) {
351                 SetVlanId av = (SetVlanId) action;
352                 outVlanId = String.valueOf(av.getVlanId());
353             }
354         }
355         if (outPorts.length() == 0) {
356             outPorts.append("*");
357         }
358         if (outVlanId == null) {
359             outVlanId = "*";
360         }
361         row.put("actions", actions.toString());
362         row.put("outPorts", outPorts.toString());
363         row.put("outVlanId", outVlanId);
364         row.put("durationSeconds",
365                 ((Integer) flowOnNode.getDurationSeconds()).toString());
366         row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
367         row.put("priority", String.valueOf(flow.getPriority()));
368         return row;
369     }
370
371     private String getNodeDesc(Node node, ISwitchManager switchManager) {
372         if (switchManager == null) {
373             return null;
374         }
375         Description desc = (Description) switchManager.getNodeProp(node, Description.propertyName);
376         return (desc == null) ? "" : desc.getValue();
377     }
378 }