Author: mes Date: 2012-07-26 14:21:06 -0700 (Thu, 26 Jul 2012) New Revision: 30006
Added: csplugins/trunk/ucsd/mes/rest-impl/ csplugins/trunk/ucsd/mes/rest-impl/pom.xml csplugins/trunk/ucsd/mes/rest-impl/src/ csplugins/trunk/ucsd/mes/rest-impl/src/main/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/CyActivator.java csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/CommandPostResponder.java csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/FunctionGetResponder.java.json csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/LocalHttpServer.java csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/R.txt csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/curl.txt csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/form.html csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/post.py Log: added rest-impl Added: csplugins/trunk/ucsd/mes/rest-impl/pom.xml =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/pom.xml (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/pom.xml 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,143 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <parent> + <artifactId>impl-parent</artifactId> + <groupId>org.cytoscape</groupId> + <version>3.0.0-alpha10-SNAPSHOT</version> + </parent> + + <properties> + <bundle.symbolicName>org.cytoscape.rest-impl</bundle.symbolicName> + <bundle.namespace>org.cytoscape.rest.internal</bundle.namespace> + </properties> + + <modelVersion>4.0.0</modelVersion> + <artifactId>rest-impl</artifactId> + + <name>Cytoscape Rest Impl (${project.artifactId})</name> + + <packaging>bundle</packaging> + + + <build> + <resources> + <resource> + <directory>src/main/resources</directory> + </resource> + <resource> + <directory>.</directory> + <includes> + <include>plugin.xml</include> + <include>plugin.properties</include> + <include>icons/**</include> + </includes> + </resource> + </resources> + <plugins> + <plugin> + <groupId>org.apache.felix</groupId> + <artifactId>maven-bundle-plugin</artifactId> + <version>${maven-bundle-plugin.version}</version> + <extensions>true</extensions> + <configuration> + <instructions> + <Bundle-SymbolicName>${bundle.symbolicName}</Bundle-SymbolicName> + <Bundle-Version>${project.version}</Bundle-Version> + <Export-Package>!${bundle.namespace}.*</Export-Package> + <Private-Package>${bundle.namespace}.*</Private-Package> + <Bundle-Activator>${bundle.namespace}.CyActivator</Bundle-Activator> + </instructions> + </configuration> + </plugin> + </plugins> + </build> + + <repositories> + <repository> + <id>cytoscape_snapshots</id> + <snapshots> + <enabled>true</enabled> + </snapshots> + <releases> + <enabled>false</enabled> + </releases> + <name>Cytoscape Snapshots</name> + <url>http://code.cytoscape.org/nexus/content/repositories/snapshots/</url> + </repository> + <repository> + <id>cytoscape_releases</id> + <snapshots> + <enabled>false</enabled> + </snapshots> + <releases> + <enabled>true</enabled> + </releases> + <name>Cytoscape Releases</name> + <url>http://code.cytoscape.org/nexus/content/repositories/releases/</url> + </repository> + + <repository> + <id>com.springsource.repository.bundles.release</id> + <name>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases</name> + <url>http://repository.springsource.com/maven/bundles/release</url> + </repository> + + <repository> + <id>com.springsource.repository.bundles.external</id> + <name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name> + <url>http://repository.springsource.com/maven/bundles/external</url> + </repository> + + </repositories> + + <dependencies> + <!-- dependencies needed to implement this code --> + <dependency> + <groupId>org.cytoscape</groupId> + <artifactId>command-executor-api</artifactId> + </dependency> + <dependency> + <groupId>org.cytoscape</groupId> + <artifactId>work-api</artifactId> + </dependency> + + <!-- dependency for a freely available json parser (http://www.json.org/java/) --> + <dependency> + <groupId>org.json</groupId> + <artifactId>org.json</artifactId> + <version>chargebee-1.0</version> + </dependency> + + <!-- dependency for Http server, uses the Apache HttpComponents library --> + <dependency> + <groupId>org.apache.httpcomponents</groupId> + <artifactId>httpcore-osgi</artifactId> + <version>4.2</version> + </dependency> + + <!-- dependency for ssh client to connect to karaf console for bundle apps --> + <dependency> + <groupId>org.apache.sshd</groupId> + <artifactId>sshd</artifactId> + <version>0.6.0</version> + <type>pom</type> + </dependency> + + <dependency> + <groupId>org.apache.xmlbeans</groupId> + <artifactId>com.springsource.org.apache.xmlbeans</artifactId> + <version>2.4.0</version> + </dependency> + + <dependency> + <groupId>javax.xml</groupId> + <artifactId>namespace</artifactId> + <version>1.0.1</version> + <type>pom</type> + </dependency> + + </dependencies> + + +</project> Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/CyActivator.java =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/CyActivator.java (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/CyActivator.java 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,41 @@ +package org.cytoscape.rest.internal; + +import org.cytoscape.rest.internal.net.server.CommandPostResponder; +import org.cytoscape.rest.internal.net.server.LocalHttpServer; +import org.cytoscape.command.CommandExecutorTaskFactory; +import org.cytoscape.work.SynchronousTaskManager; +import org.cytoscape.service.util.AbstractCyActivator; +import org.osgi.framework.BundleContext; + + +import java.util.Properties; +import java.util.concurrent.Executors; + +public class CyActivator extends AbstractCyActivator { + public CyActivator() { + super(); + } + + public void start(BundleContext bc) { + + final CommandExecutorTaskFactory cetf = getService(bc,CommandExecutorTaskFactory.class); + final SynchronousTaskManager stm = getService(bc,SynchronousTaskManager.class); + + + Thread serverThread = new Thread() { + + private LocalHttpServer server; + + @Override + public void run() { + server = new LocalHttpServer(2609, Executors.newSingleThreadExecutor()); + server.addPostResponder(new CommandPostResponder(cetf,stm)); + server.run(); + } + }; + serverThread.setDaemon(true); + Executors.newSingleThreadExecutor().execute(serverThread); + + } +} + Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/CommandPostResponder.java =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/CommandPostResponder.java (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/CommandPostResponder.java 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,64 @@ +package org.cytoscape.rest.internal.net.server; + +import java.util.HashMap; +import java.util.Map; +import java.net.URLDecoder; + +import org.cytoscape.command.CommandExecutorTaskFactory; +import org.cytoscape.work.SynchronousTaskManager; +import org.cytoscape.rest.internal.net.server.LocalHttpServer.Response; +import org.json.JSONObject; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * This class is responsible for handling POST requests received by the local HTTP server. + */ +public class CommandPostResponder implements LocalHttpServer.PostResponder{ + + private final CommandExecutorTaskFactory cetf; + private final SynchronousTaskManager stm; + private final static Logger logger = LoggerFactory.getLogger(CommandPostResponder.class); + + public CommandPostResponder(CommandExecutorTaskFactory cetf, SynchronousTaskManager stm) { + this.cetf = cetf; + this.stm = stm; + } + + @Override + public boolean canRespondTo(String url) throws Exception { + return (url.indexOf("cytoscape") >= 0); + } + + @Override + public Response respond(String url, String body) throws Exception { + logger.debug("POST url : " + url); + logger.debug("POST body : " + body); + String[] chunk = url.substring( url.indexOf("cytoscape") + 9 ).split("/"); + + String namespace = chunk[1]; + String command = chunk[2]; + String args = URLDecoder.decode(body.substring(5)); // trims off "data=" from body string + + String fullCommand = namespace + " " + command + " " + args; + + logger.debug("POST command : " + fullCommand); + + stm.execute(cetf.createTaskIterator(fullCommand)); + + Map<String, String> responseData = new HashMap<String, String>(); + + responseData.put("namespace",namespace); + responseData.put("command",command); + responseData.put("args",args); + responseData.put("status","success"); + + JSONObject jsonObject = new JSONObject(responseData); + + String responseBody = jsonObject.toString(); + responseBody += "\n"; + LocalHttpServer.Response response = new LocalHttpServer.Response(responseBody, "application/json"); + return response; + } +} Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/FunctionGetResponder.java.json =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/FunctionGetResponder.java.json (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/FunctionGetResponder.java.json 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,51 @@ +package org.cytoscape.rest.internal.net.server; + +import java.util.HashMap; +import java.util.Map; + +import org.cytoscape.command.CommandExecutorTaskFactory; +import org.cytoscape.work.SynchronousTaskManager; +import org.cytoscape.rest.internal.net.server.LocalHttpServer.Response; +import org.json.JSONObject; + +/** + * This class is responsible for handling POST requests received by the local HTTP server. + */ +public class FunctionGetResponder implements LocalHttpServer.PostResponder{ + + private final JSONFunctionExecutor functionExecutor; + + public FunctionGetResponder(JSONFunctionExecutor functionExecutor) { + this.functionExecutor = functionExecutor; + } + + @Override + public boolean canRespondTo(String url) throws Exception { + return true; + } + + @Override + public Response respond(String url, String body) throws Exception { + String[] full = url.split("/"); + int i = 0; + while (i<full.length) { + if (full[i].equals("cytoscape")) + break; + i++; + } + + String namespace = full[++i]; + String command = full[++i]; + String args = ""; + while (i<full.length-1) + args = args + full[++i] + "/"; + args = args.replaceAll("&"," "); + + JSONObject jsonObject = functionExecutor.execute(namespace,command,args); + + String responseBody = jsonObject.toString(); + responseBody += "\n"; + LocalHttpServer.Response response = new LocalHttpServer.Response(responseBody, "application/json"); + return response; + } +} Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/LocalHttpServer.java =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/LocalHttpServer.java (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/java/org/cytoscape/rest/internal/net/server/LocalHttpServer.java 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,407 @@ +package org.cytoscape.rest.internal.net.server; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +import java.util.Map; +import java.util.List; +import java.util.ArrayList; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.io.StringWriter; +import java.io.PrintWriter; + +import java.net.ServerSocket; +import java.net.InetAddress; +import java.net.Socket; +import java.net.URLDecoder; +import java.net.SocketTimeoutException; + +import org.apache.http.protocol.HttpService; +import org.apache.http.params.HttpParams; +import org.apache.http.params.SyncBasicHttpParams; +import org.apache.http.params.CoreConnectionPNames; +import org.apache.http.params.CoreProtocolPNames; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.protocol.HttpRequestHandler; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.protocol.ResponseConnControl; +import org.apache.http.protocol.ResponseContent; +import org.apache.http.protocol.ResponseDate; +import org.apache.http.protocol.ResponseServer; +import org.apache.http.protocol.HttpRequestHandlerRegistry; +import org.apache.http.impl.DefaultConnectionReuseStrategy; +import org.apache.http.impl.DefaultHttpResponseFactory; + +import org.apache.http.HttpServerConnection; +import org.apache.http.impl.DefaultHttpServerConnection; + +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.ConnectionClosedException; +import org.apache.http.MethodNotSupportedException; +import org.apache.http.RequestLine; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.entity.StringEntity; +import org.apache.http.util.EntityUtils; +import org.apache.http.HttpRequest; +import org.apache.http.HttpResponse; +import org.apache.http.HttpStatus; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Creates a server socket and serves http connections from localhost clients only. + */ +public class LocalHttpServer implements Runnable { + + private static final Logger logger = LoggerFactory.getLogger(LocalHttpServer.class); + + // The list of addresses allowed to query the server + public static final String[] ALLOWED_ORIGINS = new String[]{ + "http://apps3.nrnb.org", + "http://apps.cytoscape.org" + }; + + public static class Response { + final String body; + final String contentType; + + public Response(final String body, final String contentType) { + if (body == null) { + throw new IllegalArgumentException("body == null"); + } + + if (contentType == null) { + throw new IllegalArgumentException("contentType == null"); + } + + this.body = body; + this.contentType = contentType; + } + + public String getBody() { + return body; + } + + public String getContentType() { + return contentType; + } + } + + public interface GetResponder { + public boolean canRespondTo(String url) throws Exception; + public Response respond(String url) throws Exception; + } + + public interface PostResponder { + public boolean canRespondTo(String url) throws Exception; + public Response respond(String url, String body) throws Exception; + } + + + final List<GetResponder> getResponders = new ArrayList<GetResponder>(); + final List<PostResponder> postResponders = new ArrayList<PostResponder>(); + + final Executor connectionHandlerExecutor; + final int port; + + final HttpParams params; + final HttpService service; + + /** + * Initializes local http server but does not start serving incoming connections. + * @param port The port on which the http server should receive connections--should be greater + * than 1024 if the server is being executed by a non-root user. + * @param connectionHandlerExecutor executes a connection handler when an incoming socket connection is received + */ + public LocalHttpServer(final int port, final Executor connectionHandlerExecutor) { + if (port <= 0) { + throw new IllegalArgumentException("port <= 0"); + } + + this.port = port; + if (connectionHandlerExecutor == null) { + throw new IllegalArgumentException("connectionHandlerExecutor == null"); + } + + this.connectionHandlerExecutor = connectionHandlerExecutor; + + // Setup params + + params = (new SyncBasicHttpParams()) + .setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 5000) + .setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024) + .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false) + .setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true) + .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1"); + + // Setup service + + final HttpProcessor proc = new ImmutableHttpProcessor(new HttpResponseInterceptor[] { + new ResponseDate(), + new ResponseServer(), + new ResponseContent(), + new ResponseConnControl() + }); + + final HttpRequestHandlerRegistry registry = new HttpRequestHandlerRegistry(); + registry.register("*", new RequestHandlerDispatcher()); + + service = new HttpService(proc, + new DefaultConnectionReuseStrategy(), + new DefaultHttpResponseFactory(), + registry, + params); + } + + public void addGetResponder(final GetResponder getResponder) { + getResponders.add(getResponder); + } + + public void addPostResponder(final PostResponder postResponder) { + postResponders.add(postResponder); + } + + public void run() { + // Create a server socket + ServerSocket serverSocket = null; + try { + serverSocket = new ServerSocket(port, 0, InetAddress.getByName(null)); + } catch (IOException e) { + logger.error("Failed to create server socket", e); + return; + } + + logger.info("Server socket started on {}", String.format("%s:%d", serverSocket.getInetAddress().getHostAddress(), port)); + + // Keep servicing incoming connections until this thread is flagged as interrupted + while (!Thread.interrupted()) { // TODO: **interrupted is deprecated? + + // Create a new http server connection from the incoming socket + DefaultHttpServerConnection connection = null; + try { + final Socket socket = serverSocket.accept(); + logger.info("Server socket received connection from {}", socket.getInetAddress().getHostAddress()); + //System.out.println("Server socket received connection from {}" + socket.getInetAddress().getHostAddress()); + connection = new DefaultHttpServerConnection(); + connection.bind(socket, params); + } catch (IOException e) { + logger.error("Failed to initiate connection with client", e); + continue; + } + + // Dispatch an incoming connection to ConnectionHandler + final ConnectionHandler connectionHandler = new ConnectionHandler(service, connection); + connectionHandlerExecutor.execute(connectionHandler); + } + + logger.info("Server socket stopped"); + } + + /** + * Handles an incoming http connection when it is received by <code>ConnectionsReceiver</code>. + */ + class ConnectionHandler implements Runnable { + final HttpService service; + final HttpServerConnection connection; + + public ConnectionHandler(final HttpService service, final HttpServerConnection connection) { + this.service = service; + this.connection = connection; + } + + public void run() { + final HttpContext context = new BasicHttpContext(null); + try { + while (!Thread.interrupted() && connection.isOpen()) { + service.handleRequest(connection, context); + } + } catch (SocketTimeoutException e) { + // ignore, this happens normally + } catch (ConnectionClosedException e) { + // ignore, this happens normally + } catch (IOException e) { + logger.warn("Failed to complete communication with client; connection closing", e); + } catch (HttpException e) { + logger.warn("Client violated http; connection closing", e); + } finally { + try { + connection.shutdown(); + } catch (IOException e) { + + } + } + } + } + + class RequestHandlerDispatcher implements HttpRequestHandler { + public void handle(final HttpRequest request, final HttpResponse httpResponse, final HttpContext context) throws HttpException { + + // decode the uri + + final String uri = request.getRequestLine().getUri(); + String url = null; + try { + url = URLDecoder.decode(uri, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new HttpException("unable to parse uri: " + uri, e); + } + + // determine http method + + final String method = request.getRequestLine().getMethod().toLowerCase(); + logger.info("Request received. Method: " + method); + + // System.out.println("Request recvd: " + requestLine.toString()); + + // Obtain origin + Header originHeader = request.getFirstHeader("Origin"); + + String originValue = "http://apps.cytoscape.org"; +// if (originHeader != null) { + // originValue = originHeader.getValue(); + // } + + boolean originFound = false; + + for (int i = 0; i < ALLOWED_ORIGINS.length; i++) { + String allowedOrigin = ALLOWED_ORIGINS[i]; + + if (originValue != null && allowedOrigin.equals(originValue)) { + originFound = true; + } + } + + // System.out.println("Origin found? " + originFound); + + if (!originFound) { + if (originValue != null) { + setHttpResponseToError(httpResponse, HttpStatus.SC_FORBIDDEN, "Access denied", + "The app manager does not recognize the orgin " + originValue); + } else { + setHttpResponseToError(httpResponse, HttpStatus.SC_FORBIDDEN, "Access denied", + "Origin not found."); + } + return; + } + + if (method.equals("options")) { + // If the origin is on the allowed list, echo it back as the allowed origin + httpResponse.addHeader("Access-Control-Allow-Origin", originValue); + httpResponse.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS"); + httpResponse.addHeader("Access-Control-Max-Age", "1"); + httpResponse.addHeader("Access-Control-Allow-Headers", "origin, x-csrftoken, accept"); + return; + } + + // loop thru responders and see if any of them produce a response + Response response = null; + if (method.equals("get") || method.equals("head")) { + + logger.info("Number of GET responders: " + getResponders.size()); + for (final GetResponder getResponder : getResponders) { + + // catch any exceptions emitted by the responder so our server thread doesn't prematurely terminate + // and can send a coherent message back to the user + try { + if (getResponder.canRespondTo(url)) { + logger.info("Responder able to respond. Responding.."); + response = getResponder.respond(url); + break; + } + } catch (Exception e) { + setHttpResponseToInternalError(httpResponse, e); + return; + } + } + } else if (method.equals("post")) { + + // obtain the body of the post request + + String postBody = null; + if (request instanceof HttpEntityEnclosingRequest) { + final HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity(); + try { + postBody = EntityUtils.toString(entity); + } catch (IOException e) { + + } + } + + logger.info("Number of POST responders: " + postResponders.size()); + for (final PostResponder postResponder : postResponders) { + + // catch any exceptions emitted by the responder so our server thread doesn't prematurely terminate + // and can send a coherent message back to the user + + try { + if (postResponder.canRespondTo(uri)) { + logger.info("Found responder. Responding.."); + response = postResponder.respond(url, postBody); + break; + } + } catch (Exception e) { + logger.info("Found exception: " + e); + setHttpResponseToInternalError(httpResponse, e); + return; + } + } + } else { + // none of the http methods are valid, so issue an error to the client + throw new MethodNotSupportedException(String.format("\"%s\" method not supported", method)); + } + + if (response == null) { + setHttpResponseToError(httpResponse, HttpStatus.SC_NOT_FOUND, "Resource not found", null); + } else { + final String body = response.getBody(); + if (body == null) { + setHttpResponseToInternalError(httpResponse, "Responder \"%s\" returned null"); + } else { + setHttpResponse(httpResponse, HttpStatus.SC_OK, body, response.getContentType()); + httpResponse.addHeader("Access-Control-Allow-Origin", originValue != null? originValue : "*"); + } + } + } + } + + private static void setHttpResponse(final HttpResponse httpResponse, final int code, final String msg, final String contentType) throws HttpException { + httpResponse.setStatusCode(code); + try { + httpResponse.setEntity(new StringEntity(msg, contentType, "UTF-8")); + + } catch (UnsupportedEncodingException e) { + throw new HttpException("failed to issue output to client", e); + } + } + + private static void setHttpResponseToError(final HttpResponse httpResponse, final int code, final String title, final String msg) throws HttpException { + setHttpResponse(httpResponse, code, (msg == null ? + String.format("<html><body><h1>%s</h1></body></html>", title) : + String.format("<html><body><h1>%s</h1><pre>%s</pre></body></html>", title, msg)), "text/html"); + } + + private void setHttpResponseToInternalError(final HttpResponse httpResponse, final String msg) throws HttpException { + logger.warn("Failed to respond to client: {}", msg); + setHttpResponseToError(httpResponse, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Error", msg); + } + + private void setHttpResponseToInternalError(final HttpResponse httpResponse, final Throwable throwable) throws HttpException { + logger.warn("Failed to respond to client", throwable); + final StringWriter stringWriter = new StringWriter(); + throwable.printStackTrace(new PrintWriter(stringWriter)); + final String stacktrace = stringWriter.toString(); + setHttpResponseToError(httpResponse, HttpStatus.SC_INTERNAL_SERVER_ERROR, "Internal Error", stacktrace); + } +} Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/R.txt =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/R.txt (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/R.txt 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,8 @@ + +install.package("RCurl") +library("RCurl") + +res <- postForm("http://127.0.0.1:2609/cytoscape/network/load-file/",data="file=/Users/mes/galFiltered.sif", style="post") + + + Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/curl.txt =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/curl.txt (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/curl.txt 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,5 @@ + + +curl -d 'data=file="/Users/mes/galFiltered.sif"' http://127.0.0.1:2609/cytoscape/network/load-file/ + + Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/form.html =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/form.html (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/form.html 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,11 @@ +<html> +<body> +The post URL is: http://127.0.0.1:2609/cytoscape/network/load-file/ +<br/> +Put command arguments here: +<form action="http://127.0.0.1:2609/cytoscape/network/load-file/" method="post"> + <input type="text" name="data" value="file=/Users/mes/galFiltered.sif" size="50" /> + <input type="submit" /> +</form> +</body> +</html> Added: csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/post.py =================================================================== --- csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/post.py (rev 0) +++ csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/post.py 2012-07-26 21:21:06 UTC (rev 30006) @@ -0,0 +1,10 @@ +#!/usr/bin/python +import httplib, urllib +params = urllib.urlencode({'data': 'file=/Users/mes/galFiltered.sif'}) +headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"} +conn = httplib.HTTPConnection("127.0.0.1:2609") +conn.request("POST", "/cytoscape/network/load-file/", params, headers) +response = conn.getresponse() +print response.status, response.reason +data = response.read() +conn.close() Property changes on: csplugins/trunk/ucsd/mes/rest-impl/src/main/resources/examples/post.py ___________________________________________________________________ Added: svn:executable + * -- You received this message because you are subscribed to the Google Groups "cytoscape-cvs" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/cytoscape-cvs?hl=en.
