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.switchmanager.SwitchConfig;
39 import org.opendaylight.controller.web.IOneWeb;
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 IOneWeb {
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(IOneWeb.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 // TODO: Change to use logger instead.
90 System.out.println("SwitchManager reference is NULL");
92 if (nodeSet != null) {
93 for (Node node : nodeSet) {
94 HashMap<String, String> device = new HashMap<String, String>();
95 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.getNodeIDString());
96 device.put("nodeName", switchConfig == null ? "" : switchConfig.getNodeName());
97 device.put("nodeId", node.toString());
101 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
103 List<String> guiFieldNames = new ArrayList<String>();
104 guiFieldNames.add("Node Names");
105 guiFieldNames.add("Node ID");
106 guiFieldNames.add("Statistics");
108 result.setColumnNames(guiFieldNames);
109 result.setNodeData(lines);
113 @RequestMapping(value = "/uptime", method = RequestMethod.GET)
115 public TroubleshootingJsonBean getUptime() {
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();
123 // TODO: Change to use logger instead.
124 System.out.println("SwitchManager reference is NULL");
126 if (nodeSet != null) {
127 for (Node node : nodeSet) {
128 HashMap<String, String> device = new HashMap<String, String>();
129 SwitchConfig switchConfig = switchManager.getSwitchConfig(node.getNodeIDString());
130 device.put("nodeName", switchConfig == null ? "" : switchConfig.getNodeName());
131 device.put("nodeId", node.toString());
132 TimeStamp timeStamp = (TimeStamp) switchManager.getNodeProp(
133 node, TimeStamp.TimeStampPropName);
134 Long time = (timeStamp == null) ? 0 : timeStamp.getValue();
135 String date = (time == 0) ? "" : (new Date(time)).toString();
136 device.put("connectedSince", date);
140 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
142 List<String> guiFieldNames = new ArrayList<String>();
143 guiFieldNames.add("Node Names");
144 guiFieldNames.add("Node ID");
145 guiFieldNames.add("Connected");
147 result.setColumnNames(guiFieldNames);
148 result.setNodeData(lines);
152 @RequestMapping(value = "/flowStats", method = RequestMethod.GET)
154 public TroubleshootingJsonBean getFlowStats(
155 @RequestParam("nodeId") String nodeId) {
156 Node node = Node.fromString(nodeId);
157 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
158 IStatisticsManager statisticsManager = (IStatisticsManager) ServiceHelper
159 .getInstance(IStatisticsManager.class, containerName, this);
161 List<FlowOnNode> statistics = statisticsManager.getFlows(node);
162 for (FlowOnNode stats : statistics) {
163 cells.add(this.convertFlowStatistics(node, stats));
165 List<String> columnNames = new ArrayList<String>();
166 columnNames.addAll(Arrays.asList(new String[] { "Node", "In Port",
167 "DL Src", "DL Dst", "DL Type", "DL Vlan", "NW Src", "NW Dst",
168 "NW Proto", "TP Src", "TP Dst", "Actions", "Bytes", "Packets",
169 "Time (s)", "Timeout (s)", "Out Port(s)", "Out Vlan",
171 TroubleshootingJsonBean result = new TroubleshootingJsonBean();
172 result.setColumnNames(columnNames);
173 result.setNodeData(cells);
177 @RequestMapping(value = "/portStats", method = RequestMethod.GET)
179 public TroubleshootingJsonBean getPortStats(
180 @RequestParam("nodeId") String nodeId) {
181 Node node = Node.fromString(nodeId);
182 List<HashMap<String, String>> cells = new ArrayList<HashMap<String, String>>();
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));
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);
201 private HashMap<String, String> convertPortsStatistics(
202 NodeConnectorStatistics ncStats) {
203 HashMap<String, String> row = new HashMap<String, String>();
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()));
226 private HashMap<String, String> convertFlowStatistics(Node node,
227 FlowOnNode flowOnNode) {
228 HashMap<String, String> row = new HashMap<String, String>();
229 Flow flow = flowOnNode.getFlow();
230 Match match = flow.getMatch();
231 row.put("nodeName", getNodeName(node));
232 if (match.isPresent(MatchType.IN_PORT)) {
233 row.put(MatchType.IN_PORT.id(), ((NodeConnector) flow.getMatch()
234 .getField(MatchType.IN_PORT).getValue()).getID().toString());
236 row.put(MatchType.IN_PORT.id(), "*");
238 if (match.isPresent(MatchType.DL_SRC)) {
239 row.put(MatchType.DL_SRC.id(),
240 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
241 .getField(MatchType.DL_SRC).getValue()))));
243 row.put(MatchType.DL_SRC.id(), "*");
245 if (match.isPresent(MatchType.DL_DST)) {
246 row.put(MatchType.DL_DST.id(),
247 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
248 .getField(MatchType.DL_DST).getValue()))));
250 row.put(MatchType.DL_DST.id(), "*");
252 if (match.isPresent(MatchType.DL_TYPE)) {
253 row.put(MatchType.DL_TYPE.id(),
254 EtherTypes.getEtherTypeName(((Short) flow.getMatch()
255 .getField(MatchType.DL_TYPE).getValue())));
257 row.put(MatchType.DL_TYPE.id(), "*");
260 // Some physical switch has vlan as ffff to show "any" vlan
261 if (match.isPresent(MatchType.DL_VLAN)) {
262 if (((Short) flow.getMatch().getField(MatchType.DL_VLAN).getValue())
264 row.put(MatchType.DL_VLAN.id(), "0");
266 row.put(MatchType.DL_VLAN.id(), ((Short) flow.getMatch()
267 .getField(MatchType.DL_VLAN).getValue()).toString());
270 row.put(MatchType.DL_VLAN.id(), "*");
272 if (match.isPresent(MatchType.NW_SRC)) {
273 row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
274 .getField(MatchType.NW_SRC).getValue()).getHostAddress());
276 row.put(MatchType.NW_SRC.id(), "*");
278 if (match.isPresent(MatchType.NW_DST)) {
279 row.put(MatchType.NW_DST.id(), ((InetAddress) flow.getMatch()
280 .getField(MatchType.NW_DST).getValue()).getHostAddress());
282 row.put(MatchType.NW_DST.id(), "*");
284 if (match.isPresent(MatchType.NW_PROTO)) {
285 row.put(MatchType.NW_PROTO.id(),
286 IPProtocols.getProtocolName(((Byte) flow.getMatch()
287 .getField(MatchType.NW_PROTO).getValue())));
289 row.put(MatchType.NW_PROTO.id(), "*");
291 if (match.isPresent(MatchType.TP_SRC)) {
292 Short tpSrc = (Short) (flow.getMatch().getField(MatchType.TP_SRC)
295 row.put(MatchType.TP_SRC.id(),
296 ((Integer) (tpSrc.intValue() & 0x7FFF | 0x8000))
299 row.put(MatchType.TP_SRC.id(), tpSrc.toString());
302 row.put(MatchType.TP_SRC.id(), "*");
304 if (match.isPresent(MatchType.TP_DST)) {
305 Short tpDst = (Short) (flow.getMatch().getField(MatchType.TP_DST)
308 row.put(MatchType.TP_DST.id(),
309 ((Integer) (tpDst.intValue() & 0x7FFF | 0x8000))
312 row.put(MatchType.TP_DST.id(), tpDst.toString());
315 row.put(MatchType.TP_DST.id(), "*");
318 row.put("byteCount", ((Long) flowOnNode.getByteCount()).toString());
319 row.put("packetCount", ((Long) flowOnNode.getPacketCount()).toString());
321 StringBuffer actions = new StringBuffer();
322 StringBuffer outPorts = new StringBuffer();
323 String outVlanId = null;
324 for (Action action : flow.getActions()) {
325 actions.append(action.getType().toString() + "\n");
326 if (action instanceof Output) {
327 Output ao = (Output) action;
328 if (outPorts.length() > 0) {
329 outPorts.append(" ");
331 outPorts.append(ao.getPort().getNodeConnectorIdAsString());
332 } else if (action instanceof SetVlanId) {
333 SetVlanId av = (SetVlanId) action;
334 outVlanId = String.valueOf(av.getVlanId());
337 if (outPorts.length() == 0) {
338 outPorts.append("*");
340 if (outVlanId == null) {
343 row.put("actions", actions.toString());
344 row.put("outPorts", outPorts.toString());
345 row.put("outVlanId", outVlanId);
346 row.put("durationSeconds",
347 ((Integer) flowOnNode.getDurationSeconds()).toString());
348 row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
349 row.put("priority", String.valueOf(flow.getPriority()));
353 private String getNodeName(Node node) {
354 String nodeName = "";
355 ISwitchManager switchManager = (ISwitchManager) ServiceHelper
356 .getInstance(ISwitchManager.class, containerName, this);
357 if (switchManager != null) {
358 SwitchConfig config = switchManager.getSwitchConfig(node
360 if (config != null) {
361 nodeName = config.getNodeName();