1 53 package org.bsf.remoting.http; 54 55 import org.apache.commons.logging.*; 56 import org.apache.commons.codec.binary.Base64; 57 import org.bsf.remoting.EJBDefinition; 58 import org.bsf.remoting.http.HttpServiceInvocationHandler; 59 import org.bsf.remoting.http.HttpServiceKey; 60 import org.bsf.remoting.http.HttpServiceRequest; 61 import org.bsf.remoting.http.HttpServiceResponse; 62 63 import java.io.ObjectInputStream ; 64 import java.io.ObjectOutputStream ; 65 import java.lang.reflect.Method ; 66 import java.lang.reflect.Proxy ; 67 import java.net.HttpURLConnection ; 68 import java.net.URL ; 69 import java.rmi.RemoteException ; 70 71 78 public class HttpSessionClient { 79 80 private static Log log = LogFactory.getLog( HttpSessionClient.class ); 81 82 private static int requestNb; 83 private String sessionId; 84 85 private static final String AUTHENTICATED_SERVLET = "/authenticatedHttpSession"; 86 private static final String UNAUTHENTICATED_SERVLET = "/httpSession"; 87 88 89 private static final String DEFAULT_PROTOCOL = "http"; 90 91 92 private static final String SERVER_HOST = "localHost"; 93 94 95 private static final int SERVER_PORT = 8080; 96 97 98 private static final String SERVER_CONTEXT = "remoting"; 99 100 101 private static final int DEFAULT_THREAD_COUNT = 1; 102 103 104 private static final String MIME_TYPE = "application/x-bsf"; 105 106 107 108 111 private String protocol; 112 113 114 private String host; 115 116 119 private String context; 120 121 122 123 private String login; 124 125 126 private String pass; 127 128 129 private int port = -1; 130 131 132 private int maxThreadCount = DEFAULT_THREAD_COUNT; 133 134 135 private int curUsedThread = 0; 136 137 protected static HttpSessionClient _instance = null; 139 140 143 protected HttpSessionClient() { 144 super(); 145 log.debug( "Session client created." ); 146 147 } 148 149 152 public Object invoke( EJBDefinition p_service, Method m, Object [] args ) 153 throws Throwable { 154 Object result = null; 155 156 HttpServiceRequest request = new HttpServiceRequest( 157 p_service, m.getName(), m.getParameterTypes(), args ); 158 159 result = invokeHttp( request ); 161 162 if ( result instanceof HttpServiceKey ) { 163 HttpServiceInvocationHandler service = new HttpServiceInvocationHandler( (HttpServiceKey) result ); 166 try { 167 result = Proxy.newProxyInstance( this.getClass().getClassLoader(), 168 new Class []{m.getReturnType()}, service ); 169 } catch( IllegalArgumentException e ) { 170 log.fatal( e.getLocalizedMessage(), e ); 171 throw new RuntimeException (e.getLocalizedMessage()); 172 } 173 } 174 175 return result; 176 } 177 178 179 182 public Object invoke( HttpServiceKey p_servicekey, Method m, Object [] args ) 183 throws Throwable { 184 Object result = null; 185 186 HttpServiceRequest request = new HttpServiceRequest( 187 p_servicekey, m.getName(), m.getParameterTypes(), args ); 188 189 result = invokeHttp( request ); 190 191 if ( result instanceof HttpServiceKey ) { 194 result = new HttpServiceInvocationHandler( (HttpServiceKey) result ); 195 } 196 return result; 197 } 198 199 200 203 private Object invokeHttp( HttpServiceRequest request ) throws Throwable { 204 205 String file = null; 206 207 if (isAuthenticatedCall()){ 208 file = getAuthenticatedServerFile(); 209 } else { 210 file = getUnauthenticatedServerFile(); 211 } 212 213 int port = ( this.port == -1 ) ? SERVER_PORT : this.port; 214 String host = ( this.host == null ) ? SERVER_HOST : this.host; 215 String protocol = (this.protocol == null ) ? DEFAULT_PROTOCOL : this.protocol; 216 217 try { 218 getThreadLock(); 219 220 int currentRequestNb = requestNb++; 221 log.debug( "Start remote call " + currentRequestNb + " " + request.getMethodName() ); 222 223 HttpServiceResponse httpResponse; 224 225 if ( sessionId != null ) { 227 StringBuffer sb = new StringBuffer (); 228 sb.append( file.toString() ); 229 sb.append( ";jsessionid=" ); 230 sb.append( sessionId ); 231 file = sb.toString(); 232 } 233 234 URL url = new URL ( protocol, host, port, file ); 235 236 HttpURLConnection httpURLConnection = (HttpURLConnection ) url.openConnection(); 237 httpURLConnection.setRequestMethod( "POST" ); 238 httpURLConnection.setDoOutput( true ); 239 httpURLConnection.setDoInput( true ); 240 httpURLConnection.setUseCaches( false ); 241 httpURLConnection.setRequestProperty( "Content-Type", MIME_TYPE ); 243 244 if (isAuthenticatedCall()){ 247 248 String loginAndPass = login + ':' + pass; 249 httpURLConnection.setRequestProperty("Authorization", 250 "Basic " 251 + new String (Base64.encodeBase64(loginAndPass.getBytes()))); 252 } 253 254 ObjectOutputStream oos = new ObjectOutputStream ( 255 httpURLConnection.getOutputStream() ); 256 oos.writeObject( request ); 257 oos.close(); 258 259 ObjectInputStream ois = new ObjectInputStream ( 260 httpURLConnection.getInputStream() ); 261 httpResponse = (HttpServiceResponse) ois.readObject(); 262 sessionId = httpURLConnection.getHeaderField( "jsessionid" ); 263 ois.close(); 264 httpURLConnection.disconnect(); 265 266 log.debug( "Ending remote call " + currentRequestNb ); 267 268 269 if ( httpResponse.isExceptionThrown() ) 270 throw httpResponse.getThrowable(); 271 return httpResponse.getResult(); 272 273 } catch( java.io.IOException e ) { 274 if (e instanceof RemoteException ){ 275 throw e; 276 }else{ 277 String message = "Failure during the http remote call on http://" 278 + host + ":" + port + file; 279 log.fatal( message, e ); 280 throw new RemoteException ( message, e ); 281 } 282 } catch( ClassNotFoundException e ) { 283 String message = "Failure during the http remote call"; 284 log.fatal( message, e ); 285 throw new RemoteException ( message, e ); 286 }finally{ 287 releaseThreadLock(); 288 } 289 } 290 291 292 293 298 private synchronized void getThreadLock() { 299 while ( sessionId == null && curUsedThread > 0 ) { 301 try { 302 log.debug( "No session. Only one thread is authorized. Waiting ..." ); 303 wait(); 304 } catch( InterruptedException e ) { 305 log.fatal(e); 306 throw new RuntimeException (e.getLocalizedMessage()); 307 } 308 } 309 310 while ( curUsedThread >= maxThreadCount ) { 311 try { 312 log.debug( "Max concurent http call reached. Waiting ..." ); 313 wait(); 314 } catch( InterruptedException e ) { 315 log.fatal(e); 316 throw new RuntimeException (e.getLocalizedMessage()); 317 } 318 } 319 curUsedThread++; 320 } 321 322 private synchronized void releaseThreadLock() { 323 curUsedThread--; 324 325 notify(); 326 } 327 328 329 332 public static HttpSessionClient getInstance() throws IllegalStateException { 333 if ( _instance == null ) { 334 _instance = new HttpSessionClient(); 335 } 336 return _instance; 337 } 338 339 private boolean isAuthenticatedCall() { 340 return login != null && pass != null; 341 } 342 343 344 public void setHost( String host ) { 345 this.host = host; 346 } 347 348 353 public void setProtocol( String protocol) { 354 this.protocol = protocol; 355 } 356 357 361 public void setServerFile( String serverFile ) { 362 if ( ! serverFile.endsWith("httpSession")){ 363 throw new RuntimeException ("You must use the method setContext() instead" + 364 " of the method setServerFile to define your remote call."); 365 } 366 String context = serverFile.substring(0, serverFile.length() - 11); 367 setContext(context); 368 } 369 370 377 public void setContext(String context) { 378 while (context.endsWith("/")){ 379 context = context.substring(0,context.length() -1 ); 380 } 381 this.context = context; 382 log.debug( "Server context is " + context); 383 } 384 385 388 private String getUnauthenticatedServerFile(){ 389 StringBuffer sb = new StringBuffer (); 390 sb.append('/'); 391 if (context != null){ 392 sb.append(context); 393 }else{ 394 sb.append(SERVER_CONTEXT); 395 } 396 sb.append(UNAUTHENTICATED_SERVLET); 397 return sb.toString(); 398 } 399 400 403 private String getAuthenticatedServerFile(){ 404 StringBuffer sb = new StringBuffer (); 405 sb.append('/'); 406 if (context != null){ 407 sb.append(context); 408 }else{ 409 sb.append(SERVER_CONTEXT); 410 } 411 sb.append(AUTHENTICATED_SERVLET); 412 return sb.toString(); 413 } 414 415 public void setPort( int port ) { 416 this.port = port; 417 } 418 419 public int getThreadCount() { 420 return maxThreadCount; 421 } 422 423 public void setThreadCount( int threadCount ) { 424 this.maxThreadCount = threadCount; 425 426 log.debug( "Max concurrent thread set to " + threadCount ); 427 } 428 429 430 public void setLogin(String login) { 431 this.login = login; 432 } 433 434 public void setPassword(String pass) { 435 this.pass = pass; 436 } 437 } | Popular Tags |