X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=src%2Fjalview%2Frest%2FRestHandler.java;fp=src%2Fjalview%2Frest%2FRestHandler.java;h=caec830920756d88bd9bbb1a327e99387707dfb8;hb=d6bdee9f63270a6983eda7998571126d66e62455;hp=a37882f83e468d4d9e0090191ff9ffdd8e71c329;hpb=639c433bf1162d8219b12813753c9ba38446b52e;p=jalview.git diff --git a/src/jalview/rest/RestHandler.java b/src/jalview/rest/RestHandler.java index a37882f..caec830 100644 --- a/src/jalview/rest/RestHandler.java +++ b/src/jalview/rest/RestHandler.java @@ -20,24 +20,64 @@ */ package jalview.rest; -import jalview.httpserver.AbstractRequestHandler; - +import java.io.BufferedReader; import java.io.IOException; import java.io.PrintWriter; import java.net.BindException; +import java.util.HashMap; +import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.eclipse.jetty.server.handler.ContextHandler; + +import jalview.bin.Console; +import jalview.httpserver.AbstractRequestHandler; +import jalview.httpserver.HttpServer; + /** * A simple handler to process (or delegate) HTTP requests on /jalview/rest */ public class RestHandler extends AbstractRequestHandler { + + public enum Status + { + STARTED, IN_PROGRESS, FINISHED, ERROR, NOT_RUN + } + + public interface EndpointI + { + public String getPath(); + + public String getName(); + + public String getParameters(); + + public String getDescription(); + + public void processEndpoint(HttpServletRequest request, + HttpServletResponse response); + + } + private static final String MY_PATH = "rest"; private static final String MY_NAME = "Rest"; + private String missingEndpointMessage = null; + + private boolean init = false; + + // map of method names and method handlers + private Map endpoints = null; + + protected Map getEndpoints() + { + return endpoints; + } + /** * Singleton instance of this class */ @@ -66,9 +106,9 @@ public class RestHandler extends AbstractRequestHandler * * @throws BindException */ - private RestHandler() throws BindException + protected RestHandler() throws BindException { - setPath(MY_PATH); + init(); /* * We don't register the handler here - this is done as a special case in @@ -90,17 +130,53 @@ public class RestHandler extends AbstractRequestHandler * Currently just echoes the request; add helper classes as required to * process requests */ - final String queryString = request.getQueryString(); - final String reply = "REST not yet implemented; received " - + request.getMethod() + ": " + request.getRequestURL() - + (queryString == null ? "" : "?" + queryString); - System.out.println(reply); + System.out.println(request.toString()); + if (endpoints == null) + { + final String queryString = request.getQueryString(); + final String reply = "REST not yet implemented; received " + + request.getMethod() + ": " + request.getRequestURL() + + (queryString == null ? "" : "?" + queryString); + System.out.println(reply); + + response.setHeader("Cache-Control", "no-cache/no-store"); + response.setHeader("Content-type", "text/plain"); + final PrintWriter writer = response.getWriter(); + writer.write(reply); + return; + } + + String endpointName = getRequestedEndpointName(request); + + if (!endpoints.containsKey(endpointName) + || endpoints.get(endpointName) == null) + { + + response.setHeader("Cache-Control", "no-cache/no-store"); + response.setHeader("Content-type", "text/plain"); + PrintWriter writer = response.getWriter(); + writer.write(missingEndpointMessage == null + ? "REST endpoint '" + endpointName + "' not defined" + : missingEndpointMessage); + writer.write("\n"); + writer.write("Available endpoints are:\n"); + ContextHandler ch = HttpServer.getInstance().getContextHandler(this); + String base = HttpServer.getInstance().getUri().toString(); + String contextPath = ch == null ? "" : ch.getContextPath(); + for (String key : endpoints.keySet()) + { + writer.write(base + contextPath + "/" + key + "\n"); + } + response.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return; + } response.setHeader("Cache-Control", "no-cache/no-store"); response.setHeader("Content-type", "text/plain"); - final PrintWriter writer = response.getWriter(); - writer.write(reply); - writer.close(); + EndpointI ep = endpoints.get(endpointName); + ep.processEndpoint(request, response); + + return; } /** @@ -112,4 +188,102 @@ public class RestHandler extends AbstractRequestHandler return MY_NAME; } -} + /** + * Initialise methods + * + * @throws BindException + */ + protected void init() throws BindException + { + init(MY_PATH); + } + + protected void init(String path) throws BindException + { + setPath(path); + // Override this in extended class + // e.g. registerHandler and addEndpoints + } + + protected boolean addEndpoint(EndpointI ep) + { + if (endpoints == null) + { + endpoints = new HashMap<>(); + } + AbstractEndpoint e = (AbstractEndpoint) ep; + endpoints.put(ep.getPath(), ep); + return true; + } + + protected String getRequestedEndpointName(HttpServletRequest request) + { + String pathInfo = request.getPathInfo(); + int slashpos = pathInfo.indexOf('/', 1); + return slashpos > 1 ? pathInfo.substring(1, slashpos) + : pathInfo.substring(1); + } + + protected String[] getEndpointPathParameters(HttpServletRequest request) + { + String pathInfo = request.getPathInfo(); + int slashpos = pathInfo.indexOf('/', 1); + return slashpos < 1 ? null + : pathInfo.substring(slashpos + 1).split("/"); + } + + protected void returnError(HttpServletRequest request, + HttpServletResponse response, String message) + { + response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + String endpointName = getRequestedEndpointName(request); + Console.error(getName() + " error: endpoint " + endpointName + + " failed: '" + message + "'"); + try + { + PrintWriter writer = response.getWriter(); + writer.write("Endpoint " + endpointName + ": " + message); + } catch (IOException e) + { + Console.debug("Could not write to REST response for endpoint " + + endpointName, e); + } + } + + protected void returnStatus(HttpServletResponse response, String id, + Status status) + { + try + { + PrintWriter writer = response.getWriter(); + if (id != null) + writer.write("id=" + id + "\n"); + if (status != null) + writer.write("status=" + status.toString() + "\n"); + } catch (IOException e) + { + Console.debug("Could not write status to REST response for id:" + id, + e); + } + } + + protected String getRequestBody(HttpServletRequest request) + throws IOException + { + StringBuilder sb = new StringBuilder(); + BufferedReader reader = request.getReader(); + try + { + String line; + while ((line = reader.readLine()) != null) + { + sb.append(line).append('\n'); + } + } finally + { + reader.close(); + } + return sb.toString(); + } + +} \ No newline at end of file