2 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.troubleshoot.web;
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;
19 import org.opendaylight.controller.sal.action.Action;
20 import org.opendaylight.controller.sal.action.Output;
21 import org.opendaylight.controller.sal.action.SetVlanId;
22 import org.opendaylight.controller.sal.authorization.UserLevel;
23 import org.opendaylight.controller.sal.core.Node;
24 import org.opendaylight.controller.sal.core.NodeConnector;
25 import org.opendaylight.controller.sal.core.TimeStamp;
26 import org.opendaylight.controller.sal.flowprogrammer.Flow;
27 import org.opendaylight.controller.sal.match.Match;
28 import org.opendaylight.controller.sal.match.MatchType;
29 import org.opendaylight.controller.sal.reader.FlowOnNode;
30 import org.opendaylight.controller.sal.reader.NodeConnectorStatistics;
31 import org.opendaylight.controller.sal.utils.EtherTypes;
32 import org.opendaylight.controller.sal.utils.GlobalConstants;
33 import org.opendaylight.controller.sal.utils.HexEncode;
34 import org.opendaylight.controller.sal.utils.IPProtocols;
35 import org.opendaylight.controller.sal.utils.ServiceHelper;
36 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
37 import org.opendaylight.controller.switchmanager.ISwitchManager;
38 import org.opendaylight.controller.web.IOneWeb;
39 import org.springframework.stereotype.Controller;
40 import org.springframework.web.bind.annotation.RequestMapping;
41 import org.springframework.web.bind.annotation.RequestMethod;
42 import org.springframework.web.bind.annotation.RequestParam;
43 import org.springframework.web.bind.annotation.ResponseBody;
47 public class Troubleshoot implements IOneWeb {
48 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
49 private final String WEB_NAME = "Troubleshoot";
50 private final String WEB_ID = "troubleshoot";
51 private final short WEB_ORDER = 4;
52 private final String containerName = GlobalConstants.DEFAULT.toString();
54 public Troubleshoot() {
55 ServiceHelper.registerGlobalService(IOneWeb.class, this, null);
59 public String getWebName() {
64 public String getWebId() {
69 public short getWebOrder() {
74 public boolean isAuthorized(UserLevel userLevel) {
75 return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
78 @RequestMapping(value = "/existingNodes", method = RequestMethod.GET)
80 public TroubleshootingJsonBean getExistingNodes() {
81 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
82 .getInstance(ISwitchManager.class, containerName, this);
83 List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
84 Set<Node> nodeSet = null;
85 if (switchManager != null) {
86 nodeSet = switchManager.getNodes();
88 if (nodeSet != null) {
89 for (Node node : nodeSet) {
90 HashMap<String, String> device = new HashMap<String, String>();
91 device.put("nodeName", switchManager.getNodeDescription(node));
92 device.put("nodeId", node.toString());
96 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
98 List<String> guiFieldNames = new ArrayList<String>();
99 guiFieldNames.add("Node");
100 guiFieldNames.add("Node ID");
101 guiFieldNames.add("Statistics");
103 result.setColumnNames(guiFieldNames);
104 result.setNodeData(lines);
108 @RequestMapping(value = "/uptime", method = RequestMethod.GET)
110 public TroubleshootingJsonBean getUptime() {
111 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
112 .getInstance(ISwitchManager.class, containerName, this);
113 List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
114 Set<Node> nodeSet = null;
115 if (switchManager != null) {
116 nodeSet = switchManager.getNodes();
118 if (nodeSet != null) {
119 for (Node node : nodeSet) {
120 HashMap<String, String> device = new HashMap<String, String>();
121 device.put("nodeName", switchManager.getNodeDescription(node));
122 device.put("nodeId", node.toString());
123 TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
124 node, TimeStamp.TimeStampPropName);
125 Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
126 String date = (time == 0) ? "" : (new Date(time)).toString();
127 device.put("connectedSince", date);
131 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
133 List<String> guiFieldNames = new ArrayList<String>();
134 guiFieldNames.add("Node");
135 guiFieldNames.add("Node ID");
136 guiFieldNames.add("Connected");
138 result.setColumnNames(guiFieldNames);
139 result.setNodeData(lines);
143 @RequestMapping(value = "/flowStats", method = RequestMethod.GET)
145 public TroubleshootingJsonBean getFlowStats(
146 @RequestParam("nodeId") String nodeId) {
147 Node node = Node.fromString(nodeId);
148 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
149 IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
150 .getInstance(IStatisticsManager.class, containerName, this);
152 List<FlowOnNode> statistics = statisticsManager.getFlows(node);
153 for (FlowOnNode stats : statistics) {
154 cells.add(this.convertFlowStatistics(node, stats));
156 List<String> columnNames = new ArrayList<String>();
157 columnNames.addAll(Arrays.asList(new String[] { "Node", "In Port",
158 "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
159 "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
160 "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
162 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
163 result.setColumnNames(columnNames);
164 result.setNodeData(cells);
168 @RequestMapping(value = "/portStats", method = RequestMethod.GET)
170 public TroubleshootingJsonBean getPortStats(
171 @RequestParam("nodeId") String nodeId) {
172 Node node = Node.fromString(nodeId);
173 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
174 IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
175 .getInstance(IStatisticsManager.class, containerName, this);
176 List<NodeConnectorStatistics> statistics = statisticsManager
177 .getNodeConnectorStatistics(node);
178 for (NodeConnectorStatistics stats : statistics) {
179 cells.add(this.convertPortsStatistics(stats));
181 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
182 List<String> columnNames = new ArrayList<String>();
183 columnNames.addAll(Arrays.asList(new String[] { "Node Connector",
184 "Rx Pkts", "Tx Pkts", "Rx Bytes", "Tx Bytes", "Rx Drops",
185 "Tx Drops", "Rx Errs", "Tx Errs", "Rx Frame Errs",
186 "Rx OverRun Errs", "Rx CRC Errs", "Collisions" }));
187 result.setColumnNames(columnNames);
188 result.setNodeData(cells);
192 private HashMap<String, String> convertPortsStatistics(
193 NodeConnectorStatistics ncStats) {
194 HashMap<String, String> row = new HashMap<String, String>();
196 row.put("nodeConnector",
197 String.valueOf(ncStats.getNodeConnector().toString()));
198 row.put("rxPkts", String.valueOf(ncStats.getReceivePacketCount()));
199 row.put("txPkts", String.valueOf(ncStats.getTransmitPacketCount()));
200 row.put("rxBytes", String.valueOf(ncStats.getReceiveByteCount()));
201 row.put("txBytes", String.valueOf(ncStats.getTransmitByteCount()));
202 row.put("rxDrops", String.valueOf(ncStats.getReceiveDropCount()));
203 row.put("txDrops", String.valueOf(ncStats.getTransmitDropCount()));
204 row.put("rxErrors", String.valueOf(ncStats.getReceiveErrorCount()));
205 row.put("txErrors", String.valueOf(ncStats.getTransmitErrorCount()));
206 row.put("rxFrameErrors",
207 String.valueOf(ncStats.getReceiveFrameErrorCount()));
208 row.put("rxOverRunErrors",
209 String.valueOf(ncStats.getReceiveOverRunErrorCount()));
210 row.put("rxCRCErrors",
211 String.valueOf(ncStats.getReceiveCRCErrorCount()));
212 row.put("collisions", String.valueOf(ncStats.getCollisionCount()));
217 private HashMap<String, String> convertFlowStatistics(Node node,
218 FlowOnNode flowOnNode) {
219 HashMap<String, String> row = new HashMap<String, String>();
220 Flow flow = flowOnNode.getFlow();
221 Match match = flow.getMatch();
222 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
223 .getInstance(ISwitchManager.class, containerName, this);
224 String desc = (switchManager == null)?
225 "" : switchManager.getNodeDescription(node);
226 desc = (desc.isEmpty() || desc.equalsIgnoreCase("none"))?
227 node.toString(): desc;
228 row.put("nodeName", desc);
229 if (match.isPresent(MatchType.IN_PORT)) {
230 row.put(MatchType.IN_PORT.id(), ((NodeConnector) flow.getMatch()
231 .getField(MatchType.IN_PORT).getValue()).getID().toString());
233 row.put(MatchType.IN_PORT.id(), "*");
235 if (match.isPresent(MatchType.DL_SRC)) {
236 row.put(MatchType.DL_SRC.id(),
237 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
238 .getField(MatchType.DL_SRC).getValue()))));
240 row.put(MatchType.DL_SRC.id(), "*");
242 if (match.isPresent(MatchType.DL_DST)) {
243 row.put(MatchType.DL_DST.id(),
244 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
245 .getField(MatchType.DL_DST).getValue()))));
247 row.put(MatchType.DL_DST.id(), "*");
249 if (match.isPresent(MatchType.DL_TYPE)) {
250 row.put(MatchType.DL_TYPE.id(),
251 EtherTypes.getEtherTypeName(((Short) flow.getMatch()
252 .getField(MatchType.DL_TYPE).getValue())));
254 row.put(MatchType.DL_TYPE.id(), "*");
257 // Some physical switch has vlan as ffff to show "any" vlan
258 if (match.isPresent(MatchType.DL_VLAN)) {
259 if (((Short) flow.getMatch().getField(MatchType.DL_VLAN).getValue())
261 row.put(MatchType.DL_VLAN.id(), "0");
263 row.put(MatchType.DL_VLAN.id(), ((Short) flow.getMatch()
264 .getField(MatchType.DL_VLAN).getValue()).toString());
267 row.put(MatchType.DL_VLAN.id(), "*");
269 if (match.isPresent(MatchType.NW_SRC)) {
270 row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
271 .getField(MatchType.NW_SRC).getValue()).getHostAddress());
273 row.put(MatchType.NW_SRC.id(), "*");
275 if (match.isPresent(MatchType.NW_DST)) {
276 row.put(MatchType.NW_DST.id(), ((InetAddress) flow.getMatch()
277 .getField(MatchType.NW_DST).getValue()).getHostAddress());
279 row.put(MatchType.NW_DST.id(), "*");
281 if (match.isPresent(MatchType.NW_PROTO)) {
282 row.put(MatchType.NW_PROTO.id(),
283 IPProtocols.getProtocolName(((Byte) flow.getMatch()
284 .getField(MatchType.NW_PROTO).getValue())));
286 row.put(MatchType.NW_PROTO.id(), "*");
288 if (match.isPresent(MatchType.TP_SRC)) {
289 Short tpSrc = (Short) (flow.getMatch().getField(MatchType.TP_SRC)
292 row.put(MatchType.TP_SRC.id(),
293 ((Integer) (tpSrc.intValue() & 0x7FFF | 0x8000))
296 row.put(MatchType.TP_SRC.id(), tpSrc.toString());
299 row.put(MatchType.TP_SRC.id(), "*");
301 if (match.isPresent(MatchType.TP_DST)) {
302 Short tpDst = (Short) (flow.getMatch().getField(MatchType.TP_DST)
305 row.put(MatchType.TP_DST.id(),
306 ((Integer) (tpDst.intValue() & 0x7FFF | 0x8000))
309 row.put(MatchType.TP_DST.id(), tpDst.toString());
312 row.put(MatchType.TP_DST.id(), "*");
315 row.put("byteCount", ((Long) flowOnNode.getByteCount()).toString());
316 row.put("packetCount", ((Long) flowOnNode.getPacketCount()).toString());
318 StringBuffer actions = new StringBuffer();
319 StringBuffer outPorts = new StringBuffer();
320 String outVlanId = null;
321 for (Action action : flow.getActions()) {
322 actions.append(action.getType().toString() + "\n");
323 if (action instanceof Output) {
324 Output ao = (Output) action;
325 if (outPorts.length() > 0) {
326 outPorts.append(" ");
328 outPorts.append(ao.getPort().getNodeConnectorIdAsString());
329 } else if (action instanceof SetVlanId) {
330 SetVlanId av = (SetVlanId) action;
331 outVlanId = String.valueOf(av.getVlanId());
334 if (outPorts.length() == 0) {
335 outPorts.append("*");
337 if (outVlanId == null) {
340 row.put("actions", actions.toString());
341 row.put("outPorts", outPorts.toString());
342 row.put("outVlanId", outVlanId);
343 row.put("durationSeconds",
344 ((Integer) flowOnNode.getDurationSeconds()).toString());
345 row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
346 row.put("priority", String.valueOf(flow.getPriority()));