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.NetUtils;
36 import org.opendaylight.controller.sal.utils.ServiceHelper;
37 import org.opendaylight.controller.statisticsmanager.IStatisticsManager;
38 import org.opendaylight.controller.switchmanager.ISwitchManager;
39 import org.opendaylight.controller.web.IDaylightWeb;
40 import org.springframework.stereotype.Controller;
41 import org.springframework.web.bind.annotation.RequestMapping;
42 import org.springframework.web.bind.annotation.RequestMethod;
43 import org.springframework.web.bind.annotation.RequestParam;
44 import org.springframework.web.bind.annotation.ResponseBody;
48 public class Troubleshoot implements IDaylightWeb {
49 private static final UserLevel AUTH_LEVEL = UserLevel.CONTAINERUSER;
50 private final String WEB_NAME = "Troubleshoot";
51 private final String WEB_ID = "troubleshoot";
52 private final short WEB_ORDER = 4;
53 private final String containerName = GlobalConstants.DEFAULT.toString();
55 public Troubleshoot() {
56 ServiceHelper.registerGlobalService(IDaylightWeb.class, this, null);
60 public String getWebName() {
65 public String getWebId() {
70 public short getWebOrder() {
75 public boolean isAuthorized(UserLevel userLevel) {
76 return userLevel.ordinal() <= AUTH_LEVEL.ordinal();
79 @RequestMapping(value = "/existingNodes", method = RequestMethod.GET)
81 public TroubleshootingJsonBean getExistingNodes() {
82 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
83 .getInstance(ISwitchManager.class, containerName, this);
84 List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
85 Set<Node> nodeSet = null;
86 if (switchManager != null) {
87 nodeSet = switchManager.getNodes();
89 if (nodeSet != null) {
90 for (Node node : nodeSet) {
91 HashMap<String, String> device = new HashMap<String, String>();
92 device.put("nodeName", switchManager.getNodeDescription(node));
93 device.put("nodeId", node.toString());
97 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
99 List<String> guiFieldNames = new ArrayList<String>();
100 guiFieldNames.add("Node");
101 guiFieldNames.add("Node ID");
102 guiFieldNames.add("Statistics");
104 result.setColumnNames(guiFieldNames);
105 result.setNodeData(lines);
109 @RequestMapping(value = "/uptime", method = RequestMethod.GET)
111 public TroubleshootingJsonBean getUptime() {
112 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
113 .getInstance(ISwitchManager.class, containerName, this);
114 List<HashMap<String, String>> lines = new ArrayList<HashMap<String, String>>();
115 Set<Node> nodeSet = null;
116 if (switchManager != null) {
117 nodeSet = switchManager.getNodes();
119 if (nodeSet != null) {
120 for (Node node : nodeSet) {
121 HashMap<String, String> device = new HashMap<String, String>();
122 device.put("nodeName", switchManager.getNodeDescription(node));
123 device.put("nodeId", node.toString());
124 TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
125 node, TimeStamp.TimeStampPropName);
126 Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
127 String date = (time == 0) ? "" : (new Date(time)).toString();
128 device.put("connectedSince", date);
132 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
134 List<String> guiFieldNames = new ArrayList<String>();
135 guiFieldNames.add("Node");
136 guiFieldNames.add("Node ID");
137 guiFieldNames.add("Connected");
139 result.setColumnNames(guiFieldNames);
140 result.setNodeData(lines);
144 @RequestMapping(value = "/flowStats", method = RequestMethod.GET)
146 public TroubleshootingJsonBean getFlowStats(
147 @RequestParam("nodeId") String nodeId) {
148 Node node = Node.fromString(nodeId);
149 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
150 IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
151 .getInstance(IStatisticsManager.class, containerName, this);
153 List<FlowOnNode> statistics = statisticsManager.getFlows(node);
154 for (FlowOnNode stats : statistics) {
155 cells.add(this.convertFlowStatistics(node, stats));
157 List<String> columnNames = new ArrayList<String>();
158 columnNames.addAll(Arrays.asList(new String[] { "Node", "In Port",
159 "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
160 "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
161 "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
163 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
164 result.setColumnNames(columnNames);
165 result.setNodeData(cells);
169 @RequestMapping(value = "/portStats", method = RequestMethod.GET)
171 public TroubleshootingJsonBean getPortStats(
172 @RequestParam("nodeId") String nodeId) {
173 Node node = Node.fromString(nodeId);
174 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
175 IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
176 .getInstance(IStatisticsManager.class, containerName, this);
177 List<NodeConnectorStatistics> statistics = statisticsManager
178 .getNodeConnectorStatistics(node);
179 for (NodeConnectorStatistics stats : statistics) {
180 cells.add(this.convertPortsStatistics(stats));
182 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
183 List<String> columnNames = new ArrayList<String>();
184 columnNames.addAll(Arrays.asList(new String[] { "Node Connector",
185 "Rx Pkts", "Tx Pkts", "Rx Bytes", "Tx Bytes", "Rx Drops",
186 "Tx Drops", "Rx Errs", "Tx Errs", "Rx Frame Errs",
187 "Rx OverRun Errs", "Rx CRC Errs", "Collisions" }));
188 result.setColumnNames(columnNames);
189 result.setNodeData(cells);
193 private HashMap<String, String> convertPortsStatistics(
194 NodeConnectorStatistics ncStats) {
195 HashMap<String, String> row = new HashMap<String, String>();
197 row.put("nodeConnector",
198 String.valueOf(ncStats.getNodeConnector().toString()));
199 row.put("rxPkts", String.valueOf(ncStats.getReceivePacketCount()));
200 row.put("txPkts", String.valueOf(ncStats.getTransmitPacketCount()));
201 row.put("rxBytes", String.valueOf(ncStats.getReceiveByteCount()));
202 row.put("txBytes", String.valueOf(ncStats.getTransmitByteCount()));
203 row.put("rxDrops", String.valueOf(ncStats.getReceiveDropCount()));
204 row.put("txDrops", String.valueOf(ncStats.getTransmitDropCount()));
205 row.put("rxErrors", String.valueOf(ncStats.getReceiveErrorCount()));
206 row.put("txErrors", String.valueOf(ncStats.getTransmitErrorCount()));
207 row.put("rxFrameErrors",
208 String.valueOf(ncStats.getReceiveFrameErrorCount()));
209 row.put("rxOverRunErrors",
210 String.valueOf(ncStats.getReceiveOverRunErrorCount()));
211 row.put("rxCRCErrors",
212 String.valueOf(ncStats.getReceiveCRCErrorCount()));
213 row.put("collisions", String.valueOf(ncStats.getCollisionCount()));
218 private HashMap<String, String> convertFlowStatistics(Node node,
219 FlowOnNode flowOnNode) {
220 HashMap<String, String> row = new HashMap<String, String>();
221 Flow flow = flowOnNode.getFlow();
222 Match match = flow.getMatch();
223 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
224 .getInstance(ISwitchManager.class, containerName, this);
225 String desc = (switchManager == null)?
226 "" : switchManager.getNodeDescription(node);
227 desc = (desc.isEmpty() || desc.equalsIgnoreCase("none"))?
228 node.toString(): desc;
229 row.put("nodeName", desc);
230 if (match.isPresent(MatchType.IN_PORT)) {
231 row.put(MatchType.IN_PORT.id(), ((NodeConnector) flow.getMatch()
232 .getField(MatchType.IN_PORT).getValue())
233 .getNodeConnectorIdAsString());
235 row.put(MatchType.IN_PORT.id(), "*");
237 if (match.isPresent(MatchType.DL_SRC)) {
238 row.put(MatchType.DL_SRC.id(),
239 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
240 .getField(MatchType.DL_SRC).getValue()))));
242 row.put(MatchType.DL_SRC.id(), "*");
244 if (match.isPresent(MatchType.DL_DST)) {
245 row.put(MatchType.DL_DST.id(),
246 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
247 .getField(MatchType.DL_DST).getValue()))));
249 row.put(MatchType.DL_DST.id(), "*");
251 if (match.isPresent(MatchType.DL_TYPE)) {
252 row.put(MatchType.DL_TYPE.id(),
253 EtherTypes.getEtherTypeName(((Short) flow.getMatch()
254 .getField(MatchType.DL_TYPE).getValue())));
256 row.put(MatchType.DL_TYPE.id(), "*");
259 // Some physical switch has vlan as ffff to show "any" vlan
260 if (match.isPresent(MatchType.DL_VLAN)) {
261 if (((Short) flow.getMatch().getField(MatchType.DL_VLAN).getValue())
263 row.put(MatchType.DL_VLAN.id(), "0");
265 row.put(MatchType.DL_VLAN.id(), ((Short) flow.getMatch()
266 .getField(MatchType.DL_VLAN).getValue()).toString());
269 row.put(MatchType.DL_VLAN.id(), "*");
271 if (match.isPresent(MatchType.NW_SRC)) {
272 row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
273 .getField(MatchType.NW_SRC).getValue()).getHostAddress());
275 row.put(MatchType.NW_SRC.id(), "*");
277 if (match.isPresent(MatchType.NW_DST)) {
278 row.put(MatchType.NW_DST.id(), ((InetAddress) flow.getMatch()
279 .getField(MatchType.NW_DST).getValue()).getHostAddress());
281 row.put(MatchType.NW_DST.id(), "*");
283 if (match.isPresent(MatchType.NW_PROTO)) {
284 row.put(MatchType.NW_PROTO.id(),
285 IPProtocols.getProtocolName(((Byte) flow.getMatch()
286 .getField(MatchType.NW_PROTO).getValue())));
288 row.put(MatchType.NW_PROTO.id(), "*");
290 if (match.isPresent(MatchType.TP_SRC)) {
291 Short tpSrc = (Short) (flow.getMatch().getField(MatchType.TP_SRC)
293 row.put(MatchType.TP_SRC.id(),
294 String.valueOf(NetUtils.getUnsignedShort(tpSrc)));
296 row.put(MatchType.TP_SRC.id(), "*");
298 if (match.isPresent(MatchType.TP_DST)) {
299 Short tpDst = (Short) (flow.getMatch().getField(MatchType.TP_DST)
301 row.put(MatchType.TP_DST.id(),
302 String.valueOf(NetUtils.getUnsignedShort(tpDst)));
304 row.put(MatchType.TP_DST.id(), "*");
307 row.put("byteCount", ((Long) flowOnNode.getByteCount()).toString());
308 row.put("packetCount", ((Long) flowOnNode.getPacketCount()).toString());
310 StringBuffer actions = new StringBuffer();
311 StringBuffer outPorts = new StringBuffer();
312 String outVlanId = null;
313 for (Action action : flow.getActions()) {
314 actions.append(action.getType().toString() + "\n");
315 if (action instanceof Output) {
316 Output ao = (Output) action;
317 if (outPorts.length() > 0) {
318 outPorts.append(" ");
320 outPorts.append(ao.getPort().getNodeConnectorIdAsString());
321 } else if (action instanceof SetVlanId) {
322 SetVlanId av = (SetVlanId) action;
323 outVlanId = String.valueOf(av.getVlanId());
326 if (outPorts.length() == 0) {
327 outPorts.append("*");
329 if (outVlanId == null) {
332 row.put("actions", actions.toString());
333 row.put("outPorts", outPorts.toString());
334 row.put("outVlanId", outVlanId);
335 row.put("durationSeconds",
336 ((Integer) flowOnNode.getDurationSeconds()).toString());
337 row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
338 row.put("priority", String.valueOf(flow.getPriority()));