mev-4.0.01/source/org/tigr/remote/gateway/GatewayServlet.java

Code
Comments
Other
Rev Date Author Line
2 26 Feb 07 jari 1 /*
2 26 Feb 07 jari 2 Copyright @ 1999-2003, The Institute for Genomic Research (TIGR).
2 26 Feb 07 jari 3 All rights reserved.
2 26 Feb 07 jari 4 */
2 26 Feb 07 jari 5 /*
2 26 Feb 07 jari 6  * $RCSfile: GatewayServlet.java,v $
2 26 Feb 07 jari 7  * $Revision: 1.3 $
2 26 Feb 07 jari 8  * $Date: 2005/03/10 15:30:16 $
2 26 Feb 07 jari 9  * $Author: braistedj $
2 26 Feb 07 jari 10  * $State: Exp $
2 26 Feb 07 jari 11  */
2 26 Feb 07 jari 12 package org.tigr.remote.gateway;
2 26 Feb 07 jari 13 /*
2 26 Feb 07 jari 14  Gateway:
2 26 Feb 07 jari 15    1. redirects HTTP MEV query to one of the PVM cluster nodes
2 26 Feb 07 jari 16    2. redirects HTTP responses issued by C++ PVM module back to MEV.
2 26 Feb 07 jari 17  
2 26 Feb 07 jari 18  MEV issues calculation request via HTTP POST and when polls gateway for responses
2 26 Feb 07 jari 19  using HTTP GET. Then PVM module uses HTTP POST to send response to the gateway.
2 26 Feb 07 jari 20  The Gateway redirects that response to the next incoming MEV polling request.
2 26 Feb 07 jari 21  
2 26 Feb 07 jari 22  Gateway exploits HTTP session mechanism, provided by Servlet Engine.
2 26 Feb 07 jari 23  A session is created for each MEV calculation request.
2 26 Feb 07 jari 24  Servlet engine drops a session on a timeout basis.
2 26 Feb 07 jari 25  Important: Servlet engine SHOULD be configured to use cookies to maintain HTTP sessions.
2 26 Feb 07 jari 26  
2 26 Feb 07 jari 27  Gateway has 3 entry points:
2 26 Feb 07 jari 28  1. MEV posting start-job or stop-job request ( HTTP POST )
2 26 Feb 07 jari 29     URL?post-request
2 26 Feb 07 jari 30  2. MEV polling for responses ( HTTP GET )
2 26 Feb 07 jari 31     URL?get-response
2 26 Feb 07 jari 32  3. tigr-slave ( pvm slave module ) posting progress or result ( HTTP POST )
2 26 Feb 07 jari 33     URL?post-response
2 26 Feb 07 jari 34  
2 26 Feb 07 jari 35  There URL is the adress of this Gateway servlet.
2 26 Feb 07 jari 36  
2 26 Feb 07 jari 37  PVM slave HTTP POST redirection strategy:
2 26 Feb 07 jari 38  There could be 2 kinds of PVM module responses: a progress event and a result packet.
2 26 Feb 07 jari 39  Progress event is quite short, so Gateway could store it into it's RAM in a queue. This
2 26 Feb 07 jari 40  will increase the performance of the system.
2 26 Feb 07 jari 41  The result packet is quite large, so Gateway will lock PVM post until the next MEV polling request
2 26 Feb 07 jari 42  will arrive. When, it redirects PVM post into MEV polling request.
2 26 Feb 07 jari 43  
2 26 Feb 07 jari 44  Note: Gateway was developed and tested under Apache Tomcat 3.2 in Standalone mode
2 26 Feb 07 jari 45  Requirements: Java Servlet API 2.2 or higher.
2 26 Feb 07 jari 46  */
2 26 Feb 07 jari 47
2 26 Feb 07 jari 48 import java.io.IOException;
2 26 Feb 07 jari 49
2 26 Feb 07 jari 50 import javax.servlet.ServletConfig;
2 26 Feb 07 jari 51 import javax.servlet.ServletContext;
2 26 Feb 07 jari 52 import javax.servlet.ServletException;
2 26 Feb 07 jari 53 import javax.servlet.http.Cookie;
2 26 Feb 07 jari 54 import javax.servlet.http.HttpServlet;
2 26 Feb 07 jari 55 import javax.servlet.http.HttpServletRequest;
2 26 Feb 07 jari 56 import javax.servlet.http.HttpServletResponse;
2 26 Feb 07 jari 57 import javax.servlet.http.HttpSession;
2 26 Feb 07 jari 58
2 26 Feb 07 jari 59 import org.tigr.remote.gateway.util.ServletUtil;
2 26 Feb 07 jari 60 import org.tigr.util.ConfMap;
2 26 Feb 07 jari 61
2 26 Feb 07 jari 62 public class GatewayServlet extends HttpServlet {
2 26 Feb 07 jari 63     
2 26 Feb 07 jari 64     /**
2 26 Feb 07 jari 65      * Constructs a <code>GatewayServlet</code>.
2 26 Feb 07 jari 66      */
2 26 Feb 07 jari 67     public GatewayServlet()  {
2 26 Feb 07 jari 68     }
2 26 Feb 07 jari 69     
2 26 Feb 07 jari 70     /**
2 26 Feb 07 jari 71      * Initialize this servlet from specified configuration.
2 26 Feb 07 jari 72      */
2 26 Feb 07 jari 73     public void init( ServletConfig cfg ) throws ServletException {
2 26 Feb 07 jari 74   m_config = cfg;
2 26 Feb 07 jari 75   m_ctx = cfg.getServletContext();
2 26 Feb 07 jari 76   configure();
2 26 Feb 07 jari 77     }
2 26 Feb 07 jari 78     
2 26 Feb 07 jari 79     /**
2 26 Feb 07 jari 80      * Configure this servlet.
2 26 Feb 07 jari 81      */
2 26 Feb 07 jari 82     private void configure() throws ServletException {
2 26 Feb 07 jari 83   m_properties = new ConfMap();
2 26 Feb 07 jari 84   String[] params   = { "gateway.pvm.proxy-name", "gateway.pvm.slave-name",  "gateway.pvm.root-path"};
2 26 Feb 07 jari 85   String[] defaults = { "", "tigr-slave", "/usr/local/pvm3"};
2 26 Feb 07 jari 86   String tmp;
2 26 Feb 07 jari 87   for (int  i = 0; i < params.length; i++) {
2 26 Feb 07 jari 88       tmp = m_ctx.getInitParameter( params[i] );
2 26 Feb 07 jari 89       if (tmp == null || "".equals( tmp )) {
2 26 Feb 07 jari 90     if (!"".equals( defaults[i] ))
2 26 Feb 07 jari 91         m_properties.setProperty( params[i], defaults[i] );
2 26 Feb 07 jari 92     else
2 26 Feb 07 jari 93         throw new ServletException("Undefined required parameter: " + params[i] );
2 26 Feb 07 jari 94       } else
2 26 Feb 07 jari 95     m_properties.setProperty( params[i], tmp );
2 26 Feb 07 jari 96       
2 26 Feb 07 jari 97   }
2 26 Feb 07 jari 98   m_properties.list( System.out );
2 26 Feb 07 jari 99     }
2 26 Feb 07 jari 100     
2 26 Feb 07 jari 101     /**
2 26 Feb 07 jari 102      * Executes HTTP GET request.
2 26 Feb 07 jari 103      */
2 26 Feb 07 jari 104     public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
2 26 Feb 07 jari 105   logTrace( req, "GET log" );
2 26 Feb 07 jari 106   String requestId = req.getQueryString();
2 26 Feb 07 jari 107   if (requestId == null) return;
2 26 Feb 07 jari 108   if ("get-response".equals( requestId )) {
2 26 Feb 07 jari 109       try {
2 26 Feb 07 jari 110     onMEVPollsForResponse( req, resp );
2 26 Feb 07 jari 111       } catch (Exception e) {
2 26 Feb 07 jari 112     logError( req, resp, e, "MEV polling error" );
2 26 Feb 07 jari 113     sendError( resp, "MEV polling error: " +  e.toString() );
2 26 Feb 07 jari 114       }
2 26 Feb 07 jari 115   }
2 26 Feb 07 jari 116     }
2 26 Feb 07 jari 117     
2 26 Feb 07 jari 118     /**
2 26 Feb 07 jari 119      * Executes HTTP POST request.
2 26 Feb 07 jari 120      */
2 26 Feb 07 jari 121     public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException {
2 26 Feb 07 jari 122   logTrace( req,  "POST log" );
2 26 Feb 07 jari 123   String requestId = req.getQueryString();
2 26 Feb 07 jari 124   if (requestId == null) {
2 26 Feb 07 jari 125       try {
2 26 Feb 07 jari 126     ServletUtil.bufferedRead( req.getInputStream() );
2 26 Feb 07 jari 127       } catch (IOException ex) {
2 26 Feb 07 jari 128       }
2 26 Feb 07 jari 129       logError( req, resp, new Exception("Unrecognized POST"), "" );
2 26 Feb 07 jari 130       sendError(resp, "Unrecognized POST");
2 26 Feb 07 jari 131   } else
2 26 Feb 07 jari 132       if ("post-request".equals( requestId )) {
2 26 Feb 07 jari 133     try {
2 26 Feb 07 jari 134         onMEVPostsRequest( req, resp );
2 26 Feb 07 jari 135     } catch (Exception e) {
2 26 Feb 07 jari 136         try {
2 26 Feb 07 jari 137       ServletUtil.bufferedRead( req.getInputStream() );
2 26 Feb 07 jari 138         } catch (IOException ex) {
2 26 Feb 07 jari 139         }
2 26 Feb 07 jari 140         logError( req, resp, e, "MEV POST error" );
2 26 Feb 07 jari 141         sendError( resp, "MEV POST error: " +  e.toString() );
2 26 Feb 07 jari 142     }
2 26 Feb 07 jari 143       } else if ("post-response".equals( requestId )) {
2 26 Feb 07 jari 144     try {
2 26 Feb 07 jari 145         onPVMPostsResponse( req, resp );
2 26 Feb 07 jari 146     } catch (Exception e) {
2 26 Feb 07 jari 147         try {
2 26 Feb 07 jari 148       ServletUtil.bufferedRead( req.getInputStream() );
2 26 Feb 07 jari 149         } catch (IOException ex) {
2 26 Feb 07 jari 150         }
2 26 Feb 07 jari 151         logError( req, resp, e, "PVM POST error" );
2 26 Feb 07 jari 152         sendError( resp, "PVM POST error: " +  e.toString() );
2 26 Feb 07 jari 153     }
2 26 Feb 07 jari 154       }
2 26 Feb 07 jari 155     }
2 26 Feb 07 jari 156     
2 26 Feb 07 jari 157     /**
2 26 Feb 07 jari 158      * Executes MEV POST request.
2 26 Feb 07 jari 159      */
2 26 Feb 07 jari 160     protected void onMEVPostsRequest( HttpServletRequest req, HttpServletResponse resp ) throws Exception {
2 26 Feb 07 jari 161   HttpSession session = req.getSession( false );
2 26 Feb 07 jari 162   if (session == null) {    // that means that it is the first request
2 26 Feb 07 jari 163       session = req.getSession();
2 26 Feb 07 jari 164       synchronized( session ) {
2 26 Feb 07 jari 165     session.setAttribute("MEV_SESSION", new SessionState() );
2 26 Feb 07 jari 166     MEVRequestAcceptStrategy strategy = new MEVRequestAcceptStrategy( m_properties );
2 26 Feb 07 jari 167     strategy.acceptMEVRequest( req, resp );
2 26 Feb 07 jari 168       }
2 26 Feb 07 jari 169   } else {
2 26 Feb 07 jari 170       SessionState si = (SessionState)session.getAttribute("MEV_SESSION");
2 26 Feb 07 jari 171       MEVRequestAcceptStrategy2 strategy = new MEVRequestAcceptStrategy2( si );
2 26 Feb 07 jari 172       strategy.acceptMEVRequest( req, resp );
2 26 Feb 07 jari 173   }
2 26 Feb 07 jari 174     }
2 26 Feb 07 jari 175     
2 26 Feb 07 jari 176     /**
2 26 Feb 07 jari 177      * Executes MEV polling requests.
2 26 Feb 07 jari 178      */
2 26 Feb 07 jari 179     protected void onMEVPollsForResponse( HttpServletRequest req, HttpServletResponse resp ) throws Exception {
2 26 Feb 07 jari 180   HttpSession session = req.getSession( false );
2 26 Feb 07 jari 181   if (session == null) throw new NullPointerException("Illegal call. Session has not been created ");
2 26 Feb 07 jari 182   SessionState si = (SessionState)session.getAttribute("MEV_SESSION");
2 26 Feb 07 jari 183   if (si == null) throw new NullPointerException("Illegal call. Session info has not been created for the  current session");
2 26 Feb 07 jari 184   MEVPollAcceptStrategy strategy = new MEVPollAcceptStrategy( si, m_properties );
2 26 Feb 07 jari 185   strategy.acceptPollRequest( req, resp );
2 26 Feb 07 jari 186     }
2 26 Feb 07 jari 187     
2 26 Feb 07 jari 188     /**
2 26 Feb 07 jari 189      * Executes PVM POST response.
2 26 Feb 07 jari 190      */
2 26 Feb 07 jari 191     protected void onPVMPostsResponse( HttpServletRequest req, HttpServletResponse resp ) throws Exception {
2 26 Feb 07 jari 192   HttpSession session = req.getSession( false );
2 26 Feb 07 jari 193   if (session == null) throw new NullPointerException("Illegal call. Session has has not been created ");
2 26 Feb 07 jari 194   SessionState si = (SessionState)session.getAttribute("MEV_SESSION");
2 26 Feb 07 jari 195   if (si == null) throw new NullPointerException("Illegal call. Session info has not been created for the  current session");
2 26 Feb 07 jari 196   PVMResponseAcceptStrategy strategy = new PVMResponseAcceptStrategy( si, m_properties );
2 26 Feb 07 jari 197   strategy.acceptPVMResponse( req, resp );
2 26 Feb 07 jari 198     }
2 26 Feb 07 jari 199     
2 26 Feb 07 jari 200     /**
2 26 Feb 07 jari 201      * Sends HTTP error.
2 26 Feb 07 jari 202      */
2 26 Feb 07 jari 203     protected void sendError(HttpServletResponse resp, String error ) {
2 26 Feb 07 jari 204   try {
2 26 Feb 07 jari 205       m_ctx.log("Sending HTTP 404");
2 26 Feb 07 jari 206       resp.setContentType("text/plain");
2 26 Feb 07 jari 207       resp.sendError( 404 );
2 26 Feb 07 jari 208   } catch (IOException ex) {
2 26 Feb 07 jari 209       System.err.println("Error sending error code");
2 26 Feb 07 jari 210       throw new RuntimeException( ex.toString() );
2 26 Feb 07 jari 211   }
2 26 Feb 07 jari 212     }
2 26 Feb 07 jari 213     
2 26 Feb 07 jari 214     /**
2 26 Feb 07 jari 215      * Returns true if servlet configuration is in debug mode.
2 26 Feb 07 jari 216      */
2 26 Feb 07 jari 217     private final boolean isDebugMode() {
2 26 Feb 07 jari 218   String debug = m_ctx.getInitParameter("gateway.debug");
2 26 Feb 07 jari 219   if (debug == null)
2 26 Feb 07 jari 220       return false;
2 26 Feb 07 jari 221   if (debug.equalsIgnoreCase("true"))
2 26 Feb 07 jari 222       return true;
2 26 Feb 07 jari 223   else
2 26 Feb 07 jari 224       return false;
2 26 Feb 07 jari 225     }
2 26 Feb 07 jari 226     
2 26 Feb 07 jari 227     /**
2 26 Feb 07 jari 228      * Writes a specified string to the servlet log.
2 26 Feb 07 jari 229      */
2 26 Feb 07 jari 230     protected void logTrace( HttpServletRequest req, String str  ) {
2 26 Feb 07 jari 231   if (!isDebugMode()) return;
2 26 Feb 07 jari 232   try {
2 26 Feb 07 jari 233       StringBuffer sb = new StringBuffer();
2 26 Feb 07 jari 234       sb.append("\n---------- Gateway trace message:\n");
2 26 Feb 07 jari 235       sb.append("Trace message:  " + str + "\n");
2 26 Feb 07 jari 236       sb.append("Request method: " + req.getMethod() + "\n");
2 26 Feb 07 jari 237       sb.append("Query string:   " + req.getQueryString() + "\n");
2 26 Feb 07 jari 238       sb.append("Content length: " + req.getContentLength() + "\n");
2 26 Feb 07 jari 239       sb.append("Cookies: ( session info )\n");
2 26 Feb 07 jari 240       Cookie[] cookies = req.getCookies();
2 26 Feb 07 jari 241       if (cookies == null || cookies.length == 0)
2 26 Feb 07 jari 242     sb.append("No cookies in the HTTP request\n");
2 26 Feb 07 jari 243       else {
2 26 Feb 07 jari 244     for (int i = 0; i < cookies.length; i++) {
2 26 Feb 07 jari 245         sb.append("\tName: " + cookies[i].getName() + "\t" + "Value: " + cookies[i].getValue() + "\n");
2 26 Feb 07 jari 246     }
2 26 Feb 07 jari 247       }
2 26 Feb 07 jari 248       sb.append("\n");
2 26 Feb 07 jari 249       m_ctx.log( sb.toString() );
2 26 Feb 07 jari 250   } catch (Exception e) {
2 26 Feb 07 jari 251       System.err.println("Error logging a message");
2 26 Feb 07 jari 252   }
2 26 Feb 07 jari 253     }
2 26 Feb 07 jari 254     
2 26 Feb 07 jari 255     /**
2 26 Feb 07 jari 256      * Writes a specified exception to the servlet log.
2 26 Feb 07 jari 257      */
2 26 Feb 07 jari 258     protected void logError( HttpServletRequest req, HttpServletResponse resp, Exception ex, String str  ) {
2 26 Feb 07 jari 259   try {
2 26 Feb 07 jari 260       StringBuffer sb = new StringBuffer();
2 26 Feb 07 jari 261       sb.append("\n---------- Gateway error:\n");
2 26 Feb 07 jari 262       sb.append("Error message:  " + str + "\n");
2 26 Feb 07 jari 263       sb.append("Request method: " + req.getMethod() + "\n");
2 26 Feb 07 jari 264       sb.append("Query string:   " + req.getQueryString() + "\n");
2 26 Feb 07 jari 265       sb.append("Content length: " + req.getContentLength() + "\n");
2 26 Feb 07 jari 266       sb.append("Cookies: ( session info )\n");
2 26 Feb 07 jari 267       Cookie[] cookies = req.getCookies();
2 26 Feb 07 jari 268       if (cookies == null || cookies.length == 0)
2 26 Feb 07 jari 269     sb.append("No cookies in the HTTP request\n");
2 26 Feb 07 jari 270       else {
2 26 Feb 07 jari 271     for (int i = 0; i < cookies.length; i++) {
2 26 Feb 07 jari 272         sb.append("\tName: " + cookies[i].getName() + "\t" + "Value: " + cookies[i].getValue() + "\n");
2 26 Feb 07 jari 273     }
2 26 Feb 07 jari 274       }
2 26 Feb 07 jari 275       sb.append("\n");
2 26 Feb 07 jari 276       m_ctx.log( sb.toString(), ex  );
2 26 Feb 07 jari 277   } catch (Exception e) {
2 26 Feb 07 jari 278       System.err.println("Error logging a message");
2 26 Feb 07 jari 279   }
2 26 Feb 07 jari 280     }
2 26 Feb 07 jari 281     
2 26 Feb 07 jari 282     ServletConfig m_config;
2 26 Feb 07 jari 283     ServletContext m_ctx;
2 26 Feb 07 jari 284     ConfMap m_properties;
2 26 Feb 07 jari 285 }