1 package org.sapia.ubik.rmi.server.transport.http.servlet; 2 3 import org.sapia.ubik.net.Request; 4 import org.sapia.ubik.net.ServerAddress; 5 import org.sapia.ubik.net.UriSyntaxException; 6 import org.sapia.ubik.rmi.server.Config; 7 import org.sapia.ubik.rmi.server.Log; 8 import org.sapia.ubik.rmi.server.RMICommand; 9 import org.sapia.ubik.rmi.server.Server; 10 import org.sapia.ubik.rmi.server.invocation.InvokeCommand; 11 import org.sapia.ubik.rmi.server.perf.PerfAnalyzer; 12 import org.sapia.ubik.rmi.server.transport.Connections; 13 import org.sapia.ubik.rmi.server.transport.TransportProvider; 14 import org.sapia.ubik.rmi.server.transport.http.HttpAddress; 15 import org.sapia.ubik.rmi.server.transport.http.HttpClientConnectionPool; 16 import org.sapia.ubik.rmi.server.transport.http.JdkClientConnectionPool; 17 18 import java.io.EOFException ; 19 import java.io.IOException ; 20 import java.io.InvalidClassException ; 21 import java.io.NotSerializableException ; 22 23 import java.rmi.RemoteException ; 24 25 import java.util.Collections ; 26 import java.util.HashMap ; 27 import java.util.Map ; 28 import java.util.Properties ; 29 30 import javax.servlet.http.HttpServletRequest ; 31 import javax.servlet.http.HttpServletResponse ; 32 33 34 97 public class ServletTransportProvider implements TransportProvider, 98 ServletConsts { 99 private static boolean _usesJakarta; 100 101 static { 102 try { 103 Class.forName("org.apache.commons.httpclient.HttpClient"); 104 _usesJakarta = true; 105 } catch (Exception e) { 106 } 107 } 108 109 private PerfAnalyzer _perf = PerfAnalyzer.getInstance(); 110 private ServletAddress _addr; 111 private String _transportType; 112 private Map _pools = Collections.synchronizedMap(new HashMap ()); 113 114 public ServletTransportProvider() { 115 this(DEFAULT_SERVLET_TRANSPORT_TYPE); 116 } 117 118 protected ServletTransportProvider(String transportType) { 119 _transportType = transportType; 120 } 121 122 125 public String getTransportType() { 126 return _transportType; 127 } 128 129 132 public Server newDefaultServer() throws RemoteException { 133 throw new UnsupportedOperationException ( 134 "Transport provider does not support anonymous servers/dynamic ports"); 135 } 136 137 146 public Server newServer(Properties props) throws RemoteException { 147 String servletUrl = props.getProperty(SERVLET_URL_KEY); 148 149 if (servletUrl == null) { 150 throw new RemoteException ("'" + SERVLET_URL_KEY + "' not specified"); 151 } 152 153 try { 154 return new ServletServer(_addr = new ServletAddress(servletUrl)); 155 } catch (UriSyntaxException e) { 156 throw new RemoteException ("Could not parse servlet URL property", e); 157 } 158 } 159 160 165 public void shutdown() { 166 } 167 168 171 public synchronized Connections getPoolFor(ServerAddress address) 172 throws RemoteException { 173 Connections conns; 174 175 if ((conns = (Connections) _pools.get(address)) == null) { 176 try { 177 if (_usesJakarta) { 178 conns = new HttpClientConnectionPool((HttpAddress) address); 179 } else { 180 conns = new JdkClientConnectionPool((HttpAddress) address); 181 } 182 183 _pools.put(address, conns); 184 } catch (UriSyntaxException e) { 185 throw new RemoteException ("Could not process given address", e); 186 } 187 } 188 189 return conns; 190 } 191 192 public void handleRequest(HttpServletRequest httpReq, 193 HttpServletResponse httpRes) { 194 ServletRmiConnection conn = new ServletRmiConnection(_addr, httpReq, httpRes); 195 196 Request req = new Request(conn, _addr); 197 198 if (Log.isDebug()) { 199 Log.debug(getClass(), "handling request"); 200 } 201 202 RMICommand cmd; 203 Object resp = null; 204 205 try { 206 if (Log.isDebug()) { 207 Log.debug(getClass(), "receiving command"); 208 } 209 210 cmd = (RMICommand) req.getConnection().receive(); 211 212 if (Log.isDebug()) { 213 Log.debug(getClass(), 214 "command received: " + cmd.getClass().getName() + " from " + 215 req.getConnection().getServerAddress() + '@' + cmd.getVmId()); 216 } 217 218 cmd.init(new Config(req.getServerAddress(), req.getConnection())); 219 220 try { 221 if (_perf.isEnabled()) { 222 if (cmd instanceof InvokeCommand) { 223 _perf.getTopic(getClass().getName() + ".RemoteCall").start(); 224 } 225 } 226 227 resp = cmd.execute(); 228 229 if (_perf.isEnabled()) { 230 if (cmd instanceof InvokeCommand) { 231 _perf.getTopic(getClass().getName() + ".RemoteCall").end(); 232 } 233 } 234 } catch (Throwable t) { 235 t.printStackTrace(); 236 t.fillInStackTrace(); 237 resp = t; 238 } 239 240 if (_perf.isEnabled()) { 241 if (cmd instanceof InvokeCommand) { 242 _perf.getTopic(getClass().getName() + ".SendResponse").start(); 243 } 244 } 245 246 conn.send(resp, cmd.getVmId(), cmd.getServerAddress().getTransportType()); 247 248 if (_perf.isEnabled()) { 249 if (cmd instanceof InvokeCommand) { 250 _perf.getTopic(getClass().getName() + ".SendResponse").end(); 251 } 252 } 253 } catch (RuntimeException e) { 254 Log.error(getClass(), "RuntimeException caught sending response", e); 255 256 try { 257 e.fillInStackTrace(); 258 req.getConnection().send(e); 259 } catch (IOException e2) { 260 req.getConnection().close(); 261 262 return; 263 } 264 } catch (ClassNotFoundException e) { 265 e.fillInStackTrace(); 266 Log.error(getClass(), "Class not found while receiving sending request", e); 267 268 try { 269 req.getConnection().send(e); 270 } catch (IOException e2) { 271 e2.fillInStackTrace(); 272 req.getConnection().close(); 273 274 return; 275 } 276 } catch (EOFException e) { 277 e.fillInStackTrace(); 278 req.getConnection().close(); 279 280 return; 281 } catch (java.net.SocketException e) { 282 e.fillInStackTrace(); 283 req.getConnection().close(); 284 285 return; 286 } catch (NotSerializableException e) { 287 e.fillInStackTrace(); 288 Log.error(getClass().getName(), 289 "Could not serialize class while sending response", e); 290 291 try { 292 req.getConnection().send(e); 293 } catch (IOException e2) { 294 req.getConnection().close(); 295 296 return; 297 } 298 } catch (InvalidClassException e) { 299 e.fillInStackTrace(); 300 Log.error(getClass(), "Class is invalid; object could not be sent", e); 301 302 e.fillInStackTrace(); 303 304 try { 305 req.getConnection().send(e); 306 } catch (IOException e2) { 307 req.getConnection().close(); 308 309 return; 310 } 311 } catch (java.io.IOException e) { 312 e.fillInStackTrace(); 313 314 try { 315 req.getConnection().send(e); 316 } catch (IOException e2) { 317 req.getConnection().close(); 318 319 return; 320 } 321 } 322 } 323 } 324 | Popular Tags |