/* * Copyright (c) 2013 Big Switch Networks, Inc. * * Licensed under the Eclipse Public License, Version 1.0 (the * "License"); you may not use this file except in compliance with the * License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.sdnplatform.netvirt.web; import java.util.Collection; import java.util.Date; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.openflow.protocol.OFFeaturesReply; import org.openflow.protocol.OFPhysicalPort; import org.restlet.resource.ServerResource; import org.sdnplatform.core.IControllerService; import org.sdnplatform.core.IOFSwitch; import org.sdnplatform.routing.Link; import org.sdnplatform.topology.NodePortTuple; /** * Class to provide visibility to internal in-memory data of various components * for debugging purposes. * * URI must be in one of the following forms: " + * "http://<controller-hostname>:8080/wm/netVirt/internal-debugs/ * device-manager/<query>/json * * where <query> must be one of (no quotes) * all * device=<macaddr> * device=all * switch=<dpid> * switch=all * network-address=all * network-address=<ip address as x..y.z.w> * switch-port=all * switch-port=<dpid>-<port> * * The information can be retrieved using rest API or CLI * * @author subrata * */ public class InternalDebugsResource extends ServerResource { final String BAD_MAC = "Malformed MAC address"; final String BAD_DPID = "Malformed switch DPID"; final String BAD_NW_ADDR = "Malformed network address"; final String BAD_SW_PORT = "Malformed switch-port"; final String STATUS_ERROR = "Error"; public String dateToStr(Date date) { if (date == null) { return null; } else { return date.toString(); } } /** * Used for printing contents of a Switch object for debugging in a format * that can be handled by auto-converter of java object to json object * for example Jackson converter * * If any new member is added to the IOFSwitch class then that needs to * be added to the SwitchDebugs class below for visibility in the debug * outputs * * (Jackson couldn't convert IOFSwitch class, hence had to create a * Debug version of it * * @author subrata * */ public class SwitchDebugs{ protected Map<Object, Object> attributes; protected String connectedSince; protected OFFeaturesReply featuresReply; protected String stringId; protected String channel; protected Collection<OFPhysicalPort> ports; // Broadcast cache hit by port protected Map<Short, Long> portBroadcastCacheHits; protected boolean connected; protected int actions; protected int buffers; protected int capabilities; protected byte tables; public Map<Object, Object> getAttributes() { return attributes; } public String getConnectedSince() { return connectedSince; } public OFFeaturesReply getFeaturesReply() { return featuresReply; } public String getStringId() { return stringId; } public String getChannel() { return channel; } public Collection<OFPhysicalPort> getPorts() { return ports; } public Map<Short, Long> getPortBroadcastHits() { return portBroadcastCacheHits; } public boolean isConnected() { return connected; } public SwitchDebugs(IOFSwitch sw) { attributes = sw.getAttributes(); connectedSince = dateToStr(sw.getConnectedSince()); stringId = sw.getStringId(); channel = sw.getInetAddress().toString(); ports = sw.getPorts(); portBroadcastCacheHits = sw.getPortBroadcastHits(); connected = sw.isConnected(); actions = sw.getActions(); buffers = sw.getBuffers(); capabilities = sw.getCapabilities(); tables = sw.getTables(); } } /** * Used for printing contents of a Switch-Port object for debugging in a * format that can be handled by auto-converter of java object to json * object for example Jackson converter * * @author subrata */ public class SwitchPortTupleDebugs { public SwitchDebugs swD; Integer port; public SwitchDebugs getSwD() { return swD; } public Integer getPort() { return port; } public SwitchPortTupleDebugs(NodePortTuple npt) { IControllerService controllerProvider = (IControllerService)getContext().getAttributes(). get(IControllerService.class.getCanonicalName()); IOFSwitch sw = controllerProvider.getSwitches().get(npt.getNodeId()); swD = new SwitchDebugs(sw); port = (int)(npt.getPortId()); } } public class SwitchClusterDebugs { protected Long ClusterId; protected Set<SwitchDebugs> SwitchSetDebugs; // Getters public Long getClusterId() { return ClusterId; } public Set<SwitchDebugs> getSwitchSetDebugs() { return SwitchSetDebugs; } /* Commented out by Srini. // Constructor public SwitchClusterDebugs(SwitchCluster swCluster) { ClusterId = swCluster.getId(); SwitchDebugs swDebugs; SwitchSetDebugs = new HashSet<SwitchDebugs>(); for (IOFSwitch sw : swCluster.getSwitches()) { swDebugs = new SwitchDebugs(sw); SwitchSetDebugs.add(swDebugs); } } */ } public class LinkTupleDebugs { protected SwitchPortTupleDebugs srcSwitchPortDebugs; protected SwitchPortTupleDebugs dstSwitchPortDebugs; public SwitchPortTupleDebugs getSrcSwitchPortDebugs() { return srcSwitchPortDebugs; } public SwitchPortTupleDebugs getDstSwitchPortDebugs() { return dstSwitchPortDebugs; } public LinkTupleDebugs(Link link) { NodePortTuple srcNpt = new NodePortTuple(link.getSrc(), link.getSrcPort()); NodePortTuple dstNpt = new NodePortTuple(link.getDst(), link.getDstPort()); srcSwitchPortDebugs = new SwitchPortTupleDebugs(srcNpt); dstSwitchPortDebugs = new SwitchPortTupleDebugs(dstNpt); } } public class LinkTupleSetDebugs { protected Set<LinkTupleDebugs> linkTupleSetDebugs; public LinkTupleSetDebugs(Set<Link> linkTupleSet) { LinkTupleDebugs ltDebugs; linkTupleSetDebugs = new HashSet<LinkTupleDebugs>(); if (linkTupleSet == null) return; for (Link lt : linkTupleSet) { ltDebugs = new LinkTupleDebugs(lt); linkTupleSetDebugs.add(ltDebugs); } } public Set<LinkTupleDebugs> getSwTupleSetDebugs() { return linkTupleSetDebugs; } } // This is the output structure of the JSON return object public class InternalDebugsOutput { public String status; // OK or ERROR public String reason; // reason for ERROR if any public String date; public String componentName; public String getComponentName() { return componentName; } public String getStatus() { return status; } public String getReason() { return reason; } public String getDate() { return date; } public InternalDebugsOutput(String compName) { status = "OK"; reason = "None"; date = new Date().toString(); componentName = compName; } } public enum Option { ALL, ALL_DEVICES, ALL_SWITCHES, ONE_DEVICE, ONE_SWITCH, ALL_NW_ADDRS, ONE_NW_ADDR, ALL_SW_PORTS, ONE_SW_PORT, ERROR_BAD_DPID, ERROR_BAD_MAC, ERROR, ERROR_BAD_NW_ADDR, ERROR_BAD_SW_PORT } }