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