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.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 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()).getID().toString());
234 row.put(MatchType.IN_PORT.id(), "*");
236 if (match.isPresent(MatchType.DL_SRC)) {
237 row.put(MatchType.DL_SRC.id(),
238 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
239 .getField(MatchType.DL_SRC).getValue()))));
241 row.put(MatchType.DL_SRC.id(), "*");
243 if (match.isPresent(MatchType.DL_DST)) {
244 row.put(MatchType.DL_DST.id(),
245 (HexEncode.bytesToHexString(((byte[]) flow.getMatch()
246 .getField(MatchType.DL_DST).getValue()))));
248 row.put(MatchType.DL_DST.id(), "*");
250 if (match.isPresent(MatchType.DL_TYPE)) {
251 row.put(MatchType.DL_TYPE.id(),
252 EtherTypes.getEtherTypeName(((Short) flow.getMatch()
253 .getField(MatchType.DL_TYPE).getValue())));
255 row.put(MatchType.DL_TYPE.id(), "*");
258 // Some physical switch has vlan as ffff to show "any" vlan
259 if (match.isPresent(MatchType.DL_VLAN)) {
260 if (((Short) flow.getMatch().getField(MatchType.DL_VLAN).getValue())
262 row.put(MatchType.DL_VLAN.id(), "0");
264 row.put(MatchType.DL_VLAN.id(), ((Short) flow.getMatch()
265 .getField(MatchType.DL_VLAN).getValue()).toString());
268 row.put(MatchType.DL_VLAN.id(), "*");
270 if (match.isPresent(MatchType.NW_SRC)) {
271 row.put(MatchType.NW_SRC.id(), ((InetAddress) flow.getMatch()
272 .getField(MatchType.NW_SRC).getValue()).getHostAddress());
274 row.put(MatchType.NW_SRC.id(), "*");
276 if (match.isPresent(MatchType.NW_DST)) {
277 row.put(MatchType.NW_DST.id(), ((InetAddress) flow.getMatch()
278 .getField(MatchType.NW_DST).getValue()).getHostAddress());
280 row.put(MatchType.NW_DST.id(), "*");
282 if (match.isPresent(MatchType.NW_PROTO)) {
283 row.put(MatchType.NW_PROTO.id(),
284 IPProtocols.getProtocolName(((Byte) flow.getMatch()
285 .getField(MatchType.NW_PROTO).getValue())));
287 row.put(MatchType.NW_PROTO.id(), "*");
289 if (match.isPresent(MatchType.TP_SRC)) {
290 Short tpSrc = (Short) (flow.getMatch().getField(MatchType.TP_SRC)
292 row.put(MatchType.TP_SRC.id(),
293 String.valueOf(NetUtils.getUnsignedShort(tpSrc)));
295 row.put(MatchType.TP_SRC.id(), "*");
297 if (match.isPresent(MatchType.TP_DST)) {
298 Short tpDst = (Short) (flow.getMatch().getField(MatchType.TP_DST)
300 row.put(MatchType.TP_DST.id(),
301 String.valueOf(NetUtils.getUnsignedShort(tpDst)));
303 row.put(MatchType.TP_DST.id(), "*");
306 row.put("byteCount", ((Long) flowOnNode.getByteCount()).toString());
307 row.put("packetCount", ((Long) flowOnNode.getPacketCount()).toString());
309 StringBuffer actions = new StringBuffer();
310 StringBuffer outPorts = new StringBuffer();
311 String outVlanId = null;
312 for (Action action : flow.getActions()) {
313 actions.append(action.getType().toString() + "\n");
314 if (action instanceof Output) {
315 Output ao = (Output) action;
316 if (outPorts.length() > 0) {
317 outPorts.append(" ");
319 outPorts.append(ao.getPort().getNodeConnectorIdAsString());
320 } else if (action instanceof SetVlanId) {
321 SetVlanId av = (SetVlanId) action;
322 outVlanId = String.valueOf(av.getVlanId());
325 if (outPorts.length() == 0) {
326 outPorts.append("*");
328 if (outVlanId == null) {
331 row.put("actions", actions.toString());
332 row.put("outPorts", outPorts.toString());
333 row.put("outVlanId", outVlanId);
334 row.put("durationSeconds",
335 ((Integer) flowOnNode.getDurationSeconds()).toString());
336 row.put("idleTimeout", ((Short) flow.getIdleTimeout()).toString());
337 row.put("priority", String.valueOf(flow.getPriority()));