| package net.floodlightcontroller.debugevent.web; |
| |
| |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import net.floodlightcontroller.debugevent.IDebugEventService.DebugEventInfo; |
| import net.floodlightcontroller.debugevent.IDebugEventService.EventType; |
| |
| import org.restlet.resource.Get; |
| import org.restlet.resource.Post; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| /** |
| * Web interface for Debug Events |
| * |
| * @author Saurav |
| */ |
| public class DebugEventResource extends DebugEventResourceBase { |
| protected static Logger logger = |
| LoggerFactory.getLogger(DebugEventResource.class); |
| |
| /** |
| * The output JSON model that contains the counter information |
| */ |
| public static class DebugEventInfoOutput { |
| protected class DEInfo { |
| private final boolean enabled; |
| private final int bufferCapacity; |
| private final EventType eventType; |
| private final String eventDesc; |
| private final String eventName; |
| private final String moduleName; |
| private final String[] metaData; |
| private final List<Map<String,String>> eventHistory; |
| |
| DEInfo(DebugEventInfo dei) { |
| this.moduleName = dei.getEventInfo().getModuleName(); |
| this.eventName = dei.getEventInfo().getEventName(); |
| this.eventDesc = dei.getEventInfo().getEventDesc(); |
| this.metaData = dei.getEventInfo().getMetaData(); |
| this.enabled = dei.getEventInfo().isEnabled(); |
| this.eventType = dei.getEventInfo().getEtype(); |
| this.bufferCapacity = dei.getEventInfo().getBufferCapacity(); |
| this.eventHistory = dei.getEvents(); |
| } |
| public boolean isEnabled() { |
| return enabled; |
| } |
| public int getBufferCapacity() { |
| return bufferCapacity; |
| } |
| public String getEventDesc() { |
| return eventDesc; |
| } |
| public String getEventName() { |
| return eventName; |
| } |
| public String getModuleName() { |
| return moduleName; |
| } |
| public String[] getMetaData() { |
| return metaData; |
| } |
| public EventType getEventType() { |
| return eventType; |
| } |
| public List<Map<String,String>> getEventHistory() { |
| return eventHistory; |
| } |
| |
| } |
| |
| public Map<String, DEInfo> eventMap = null; |
| public List<String> names = null; |
| public String error = null; |
| |
| DebugEventInfoOutput(boolean getList) { |
| if (!getList) { |
| eventMap = new HashMap<String, DEInfo>(); |
| } |
| } |
| public Map<String, DEInfo> getEventMap() { |
| return eventMap; |
| } |
| public List<String> getNames() { |
| return names; |
| } |
| public String getError() { |
| return error; |
| } |
| |
| } |
| |
| public enum Option { |
| ALL, ONE_MODULE, ONE_MODULE_EVENT, ERROR_BAD_MODULE_NAME, ERROR_BAD_PARAM, |
| ERROR_BAD_MODULE_EVENT_NAME |
| } |
| |
| public static class DebugEventPost { |
| public Boolean reset; |
| |
| public Boolean getReset() { |
| return reset; |
| } |
| public void setReset(Boolean reset) { |
| this.reset = reset; |
| } |
| } |
| |
| public static class ResetOutput { |
| String error = null; |
| |
| public String getError() { |
| return error; |
| } |
| public void setError(String error) { |
| this.error = error; |
| } |
| } |
| |
| /** |
| * Reset events |
| * |
| * If using curl: |
| * curl -X POST -d {\"reset\":true} -H "Content-Type: application/json" URL |
| * where URL must be in one of the following forms for resetting registered events: |
| * "http://{controller-hostname}:8080/wm/debugevent/ |
| * "http://{controller-hostname}:8080/wm/debugevent/{param1} |
| * "http://{controller-hostname}:8080/wm/debugevent/{param1}/{param2} |
| * |
| * Not giving {param1} will reset all events |
| * {param1} can be 'all' or the name of a module. The former case will reset |
| * all events, while the latter will reset all events for the moduleName (if |
| * param2 is null).{param2} must be an eventName for the given moduleName to |
| * reset a specific event. |
| */ |
| @Post |
| public ResetOutput postHandler(DebugEventPost postData) { |
| ResetOutput output = new ResetOutput(); |
| String param1 = (String)getRequestAttributes().get("param1"); |
| String param2 = (String)getRequestAttributes().get("param2"); |
| |
| if (postData.getReset() != null && postData.getReset()) { |
| Option choice = Option.ERROR_BAD_PARAM; |
| |
| if (param1 == null) { |
| param1 = "all"; |
| choice = Option.ALL; |
| } else if (param1.equals("all")) { |
| choice = Option.ALL; |
| } else if (param2 == null) { |
| boolean isRegistered = debugEvent.containsModuleName(param1); |
| if (isRegistered) { |
| choice = Option.ONE_MODULE; |
| } else { |
| choice = Option.ERROR_BAD_MODULE_NAME; |
| } |
| } else { |
| // differentiate between disabled and non-existing events |
| boolean isRegistered = debugEvent.containsModuleEventName(param1, param2); |
| if (isRegistered) { |
| choice = Option.ONE_MODULE_EVENT; |
| } else { |
| choice = Option.ERROR_BAD_MODULE_EVENT_NAME; |
| } |
| } |
| |
| switch (choice) { |
| case ALL: |
| debugEvent.resetAllEvents(); |
| break; |
| case ONE_MODULE: |
| debugEvent.resetAllModuleEvents(param1); |
| break; |
| case ONE_MODULE_EVENT: |
| debugEvent.resetSingleEvent(param1, param2); |
| break; |
| case ERROR_BAD_MODULE_NAME: |
| output.error = "Module name has no corresponding registered events"; |
| break; |
| case ERROR_BAD_MODULE_EVENT_NAME: |
| output.error = "Event not registered"; |
| break; |
| case ERROR_BAD_PARAM: |
| output.error = "Bad param"; |
| } |
| } |
| |
| return output; |
| |
| } |
| |
| /** |
| * Return the debug event data for the get rest-api call |
| * |
| * URL must be in one of the following forms for retrieving a list |
| * moduleNames "http://{controller-hostname}:8080/wm/debugevent/ |
| * counterNames "http://{controller-hostname}:8080/wm/debugevent/{moduleName} |
| * |
| * URL must be in one of the following forms for retrieving event data: |
| * "http://{controller-hostname}:8080/wm/debugevent/{param1} |
| * "http://{controller-hostname}:8080/wm/debugevent/{param1}/{param2} |
| * |
| * where {param1} must be one of (no quotes): |
| * null if nothing is given then by default the list |
| * of all moduleNames is returned for which |
| * events have been registered |
| * "all" can return value/info on all active events |
| * but is currently disallowed |
| * "{moduleName}" returns value/info on events for the specified module |
| * depending on the value of param2 |
| * and {param2} must be one of (no quotes): |
| * null returns all eventNames registered for the |
| * given moduleName (in param1) |
| * "{eventName}" returns value/info for specific event if it is active. |
| * |
| */ |
| @Get("json") |
| public DebugEventInfoOutput handleEventInfoQuery() { |
| Option choice = Option.ERROR_BAD_PARAM; |
| DebugEventInfoOutput output; |
| String laststr = getQueryValue("last"); |
| int last = Integer.MAX_VALUE; |
| try { |
| if (laststr != null) |
| last = Integer.valueOf(laststr); |
| if (last < 1) last = Integer.MAX_VALUE; |
| } catch (NumberFormatException e) { |
| output = new DebugEventInfoOutput(false); |
| output.error = "Expected an integer requesting last X events;" + |
| " received " + laststr; |
| return output; |
| } |
| String param1 = (String)getRequestAttributes().get("param1"); |
| String param2 = (String)getRequestAttributes().get("param2"); |
| |
| if (param1 == null) { |
| output = new DebugEventInfoOutput(true); |
| return listEvents(output); |
| } else if (param1.equals("all")) { |
| output = new DebugEventInfoOutput(false); |
| //populateEvents(debugEvent.getAllEventHistory(), output); |
| output.error = "Cannot retrieve all events - please select a specific event"; |
| return output; |
| } |
| |
| if (param2 == null) { |
| output = new DebugEventInfoOutput(true); |
| boolean isRegistered = debugEvent.containsModuleName(param1); |
| if (isRegistered) { |
| return listEvents(param1, output); |
| } else { |
| choice = Option.ERROR_BAD_MODULE_NAME; |
| } |
| } else if (param2.equals("all")) { |
| output = new DebugEventInfoOutput(false); |
| //choice = Option.ONE_MODULE; |
| output.error = "Cannot retrieve all events - please select a specific event"; |
| return output; |
| } else { |
| // differentiate between disabled and non-existing events |
| boolean isRegistered = debugEvent.containsModuleEventName(param1, param2); |
| if (isRegistered) { |
| choice = Option.ONE_MODULE_EVENT; |
| } else { |
| choice = Option.ERROR_BAD_MODULE_EVENT_NAME; |
| } |
| } |
| |
| output = new DebugEventInfoOutput(false); |
| switch (choice) { |
| case ONE_MODULE: |
| populateEvents(debugEvent.getModuleEventHistory(param1), output); |
| break; |
| case ONE_MODULE_EVENT: |
| populateSingleEvent(debugEvent.getSingleEventHistory(param1, param2, last), |
| output); |
| break; |
| case ERROR_BAD_MODULE_NAME: |
| output.error = "Module name has no corresponding registered events"; |
| break; |
| case ERROR_BAD_MODULE_EVENT_NAME: |
| output.error = "Event not registered"; |
| break; |
| case ERROR_BAD_PARAM: |
| default: |
| output.error = "Bad param"; |
| } |
| |
| return output; |
| } |
| |
| private DebugEventInfoOutput listEvents(DebugEventInfoOutput output) { |
| output.names = debugEvent.getModuleList(); |
| return output; |
| } |
| |
| private DebugEventInfoOutput listEvents(String moduleName, |
| DebugEventInfoOutput output) { |
| output.names = debugEvent.getModuleEventList(moduleName); |
| return output; |
| } |
| |
| private void populateSingleEvent(DebugEventInfo singleEventHistory, |
| DebugEventInfoOutput output) { |
| if (singleEventHistory != null) { |
| output.eventMap.put(singleEventHistory.getEventInfo().getModuleEventName(), |
| output.new DEInfo(singleEventHistory)); |
| } |
| } |
| |
| private void populateEvents(List<DebugEventInfo> eventHistory, |
| DebugEventInfoOutput output) { |
| if (eventHistory != null) { |
| for (DebugEventInfo de : eventHistory) |
| populateSingleEvent(de, output); |
| } |
| } |
| } |