blob: a3f06ceaf3f7ab615ae062d9e4d35d02117eb4e9 [file] [log] [blame]
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);
}
}
}