package org.wikibrain.webapi; import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.jetty.server.Request; import org.json.simple.JSONObject; import org.wikibrain.core.lang.Language; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.lang.management.ManagementFactory; import java.lang.management.ThreadMXBean; import java.util.HashMap; import java.util.Map; /** * @author Shilad Sen */ public class WikiBrainWebRequest { // For timings private ThreadMXBean bean = ManagementFactory.getThreadMXBean(); private long startCpuTime; private long startUserTime; private long elapsedUserTime; private long elapsedCpuTime; private final String target; private final Request request; private final HttpServletRequest httpServletRequest; private final HttpServletResponse httpServletResponse; public WikiBrainWebRequest(String target, Request request, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) { startCpuTime = getCpuTime(); startUserTime = getUserTime(); this.target = target; this.request = request; this.httpServletRequest = httpServletRequest; this.httpServletResponse = httpServletResponse; } private long getUserTime() { return bean.isCurrentThreadCpuTimeSupported( ) ? bean.getCurrentThreadUserTime() : 0L; } private long getCpuTime() { return bean.isCurrentThreadCpuTimeSupported( ) ? bean.getCurrentThreadCpuTime( ) : 0L; } public String getParam(String key) { return request.getParameter(key); } public String getParam(String key, String defaultValue) { return hasParam(key) ? getParam(key) : defaultValue; } public Language getLanguage() { String code = getParamOrDie("lang"); if (!Language.hasLangCode(code)) { throw new WikiBrainWebException("Unknown language code: " + code); } return Language.getByLangCode(code); } public boolean hasParam(String key) { String value = getParam(key); return (value != null && !value.trim().isEmpty()); } public String getParamOrDie(String key) { String val = getParam(key); if (val == null) { throw new WikiBrainWebException("Missing parameter " + key); } else { return val; } } public String getUserToken() { return ""; // TODO: this should return a unique token describing the user. } /** * Writes a new json response whose results hashmap contains one key and one value. * @param keysAndValues key1, value1, key2, value2, ... */ public void writeJsonResponse(Object ...keysAndValues) { if (keysAndValues.length % 2 != 0) { throw new IllegalArgumentException(); } Map obj = new HashMap(); for (int i = 0; i < keysAndValues.length; i += 2) { if (!(keysAndValues[i] instanceof String)) { throw new IllegalArgumentException("Invalid key: " + keysAndValues[i]); } obj.put(keysAndValues[i], keysAndValues[i + 1]); } writeJsonResponse(obj); } public void writeJsonResponse(Map object) { if (!object.containsKey("success")) { object.put("success", true); } if (!object.containsKey("message")) { object.put("message", ""); } this.elapsedCpuTime = getCpuTime() - startCpuTime; this.elapsedUserTime = getUserTime() - startUserTime; Map<String, Double> resources = new HashMap<String, Double>(); resources.put("cpuTime", elapsedCpuTime / 1.0E9); resources.put("userTime", elapsedUserTime / 1.0E9); object.put("diagnostics", resources); httpServletResponse.setContentType("application/json;charset=utf-8"); httpServletResponse.setStatus(HttpServletResponse.SC_OK); try { httpServletResponse.getWriter().println(JSONObject.toJSONString(object)); } catch (IOException e) { throw new WikiBrainWebException(e); } request.setHandled(true); } public void writeError(Exception e) { Map<String, Object> errorObj = new HashMap<String, Object>(); errorObj.put("message", e.getMessage()); errorObj.put("type", e.getClass().getName()); errorObj.put("details", ExceptionUtils.getStackTrace(e)); writeJsonResponse( "success", false, "message", e.getMessage(), "error", errorObj ); } }