1 45 package org.openejb.server.ejbd; 46 47 import java.io.ObjectInputStream ; 48 import java.io.ObjectOutputStream ; 49 import java.rmi.RemoteException ; 50 import java.util.Collection ; 51 52 import javax.ejb.EJBHome ; 53 import javax.ejb.EJBObject ; 54 55 import org.openejb.DeploymentInfo; 56 import org.openejb.OpenEJB; 57 import org.openejb.ProxyInfo; 58 import org.openejb.RpcContainer; 59 import org.openejb.client.EJBRequest; 60 import org.openejb.client.EJBResponse; 61 import org.openejb.client.RequestMethods; 62 import org.openejb.client.ResponseCodes; 63 import org.openejb.spi.SecurityService; 64 65 66 69 class EjbRequestHandler implements ResponseCodes, RequestMethods { 70 private final EjbDaemon daemon; 71 74 EjbRequestHandler(EjbDaemon daemon) { 75 this.daemon = daemon; 76 } 78 79 public void processRequest(ObjectInputStream in, ObjectOutputStream out) { 80 EJBRequest req = new EJBRequest(); 81 EJBResponse res = new EJBResponse(); 82 83 try { 89 req.readExternal( in ); 90 91 105 106 } catch (Throwable t) { 107 replyWithFatalError 108 (out, t, "Error caught during request processing"); 109 return; 110 } 111 112 CallContext call = null; 113 DeploymentInfo di = null; 114 RpcContainer c = null;; 115 116 try { 117 di = this.daemon.getDeployment(req); 118 } catch (RemoteException e) { 119 replyWithFatalError 120 (out, e, "No such deployment"); 121 return; 122 128 } catch ( Throwable t ) { 129 replyWithFatalError 130 (out, t, "Unkown error occured while retrieving deployment"); 131 return; 132 } 133 134 try { 135 call = CallContext.getCallContext(); 136 call.setEJBRequest( req ); 137 call.setDeploymentInfo( di ); 138 } catch ( Throwable t ) { 139 replyWithFatalError 140 (out, t, "Unable to set the thread context for this request"); 141 return; 142 } 143 144 146 try { 147 switch (req.getRequestMethod()) { 148 case EJB_OBJECT_BUSINESS_METHOD: 150 doEjbObject_BUSINESS_METHOD( req, res ); 151 break; 152 153 case EJB_HOME_CREATE: 155 doEjbHome_CREATE( req, res ); 156 break; 157 158 case EJB_HOME_FIND: 159 doEjbHome_FIND( req, res ); 160 break; 161 162 case EJB_OBJECT_GET_EJB_HOME: 164 doEjbObject_GET_EJB_HOME( req, res ); 165 break; 166 167 case EJB_OBJECT_GET_HANDLE: 168 doEjbObject_GET_HANDLE( req, res ); 169 break; 170 171 case EJB_OBJECT_GET_PRIMARY_KEY: 172 doEjbObject_GET_PRIMARY_KEY( req, res ); 173 break; 174 175 case EJB_OBJECT_IS_IDENTICAL: 176 doEjbObject_IS_IDENTICAL( req, res ); 177 break; 178 179 case EJB_OBJECT_REMOVE: 180 doEjbObject_REMOVE( req, res ); 181 break; 182 183 case EJB_HOME_GET_EJB_META_DATA: 185 doEjbHome_GET_EJB_META_DATA( req, res ); 186 break; 187 188 case EJB_HOME_GET_HOME_HANDLE: 189 doEjbHome_GET_HOME_HANDLE( req, res ); 190 break; 191 192 case EJB_HOME_REMOVE_BY_HANDLE: 193 doEjbHome_REMOVE_BY_HANDLE( req, res ); 194 break; 195 196 case EJB_HOME_REMOVE_BY_PKEY: 197 doEjbHome_REMOVE_BY_PKEY( req, res ); 198 break; 199 } 200 201 202 } catch (org.openejb.InvalidateReferenceException e) { 203 res.setResponse(EJB_SYS_EXCEPTION, e.getRootCause()); 204 } catch (org.openejb.ApplicationException e) { 205 res.setResponse(EJB_APP_EXCEPTION, e.getRootCause()); 206 } catch (org.openejb.SystemException e) { 207 res.setResponse(EJB_ERROR, e.getRootCause()); 208 this.daemon.logger.fatal( req+": OpenEJB encountered an unknown system error in container: ", e); 212 } catch (java.lang.Throwable t) { 213 replyWithFatalError 215 (out, t, "Unknown error in container"); 216 return; 217 } finally { 218 this.daemon.logger.info( "EJB RESPONSE: "+res ); 219 try { 220 res.writeExternal( out ); 221 } catch (java.io.IOException ie) { 222 this.daemon.logger.fatal("Couldn't write EjbResponse to output stream", ie); 223 } 224 call.reset(); 225 } 226 } 227 228 protected void doEjbObject_BUSINESS_METHOD( EJBRequest req, EJBResponse res ) throws Exception { 229 230 CallContext call = CallContext.getCallContext(); 231 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 232 233 Object result = c.invoke( req.getDeploymentId(), 234 req.getMethodInstance(), 235 req.getMethodParameters(), 236 req.getPrimaryKey(), 237 req.getClientIdentity()); 238 239 if (result instanceof ProxyInfo) { 240 ProxyInfo info = (ProxyInfo)result; 241 242 if ( EJBObject .class.isAssignableFrom(info.getInterface()) ) { 243 result = this.daemon.clientObjectFactory._getEJBObject(call, info); 244 } else if ( EJBHome .class.isAssignableFrom(info.getInterface()) ) { 245 result = this.daemon.clientObjectFactory._getEJBHome(call, info); 246 } else { 247 result = new RemoteException ("The container returned a ProxyInfo object that is neither a javax.ejb.EJBObject or javax.ejb.EJBHome: "+info.getInterface()); 250 this.daemon.logger.error( req + "The container returned a ProxyInfo object that is neither a javax.ejb.EJBObject or javax.ejb.EJBHome: "+info.getInterface()); 251 res.setResponse( EJB_SYS_EXCEPTION, result); 252 return; 253 } 254 } 255 256 res.setResponse( EJB_OK, result); 257 } 258 259 260 protected void doEjbHome_CREATE( EJBRequest req, EJBResponse res ) throws Exception { 262 263 CallContext call = CallContext.getCallContext(); 264 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 265 266 Object result = c.invoke( req.getDeploymentId(), 267 req.getMethodInstance(), 268 req.getMethodParameters(), 269 req.getPrimaryKey(), 270 req.getClientIdentity()); 271 272 if (result instanceof ProxyInfo) { 273 ProxyInfo info = (ProxyInfo)result; 274 res.setResponse(EJB_OK, info.getPrimaryKey()); 275 } else { 276 result = new RemoteException ("The bean is not EJB compliant. The should be created or and exception should be thrown."); 280 this.daemon.logger.error( req + "The bean is not EJB compliant. The should be created or and exception should be thrown."); 281 res.setResponse( EJB_SYS_EXCEPTION, result); 282 } 283 } 284 285 322 protected void doEjbHome_FIND( EJBRequest req, EJBResponse res ) throws Exception { 323 324 CallContext call = CallContext.getCallContext(); 325 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 326 327 Object result = c.invoke( req.getDeploymentId(), 328 req.getMethodInstance(), 329 req.getMethodParameters(), 330 req.getPrimaryKey(), 331 req.getClientIdentity()); 332 333 334 335 if ( result instanceof Collection ) { 336 337 Object [] primaryKeys = ((Collection )result).toArray(); 338 339 for (int i=0; i < primaryKeys.length; i++) { 340 primaryKeys[i] = ((ProxyInfo)primaryKeys[i]).getPrimaryKey(); 341 } 342 343 res.setResponse( EJB_OK_FOUND_COLLECTION , primaryKeys ); 344 345 } else if (result instanceof java.util.Enumeration ) { 346 347 java.util.Enumeration resultAsEnum = (java.util.Enumeration ) result; 348 java.util.List listOfPKs = new java.util.ArrayList (); 349 while ( resultAsEnum.hasMoreElements() ) { 350 listOfPKs.add( ((ProxyInfo)resultAsEnum.nextElement()).getPrimaryKey() ); 351 } 352 353 res.setResponse( EJB_OK_FOUND_ENUMERATION , listOfPKs.toArray( new Object [listOfPKs.size()]) ); 354 355 } else if (result instanceof ProxyInfo) { 356 result = ((ProxyInfo)result).getPrimaryKey(); 357 res.setResponse( EJB_OK_FOUND , result ); 358 359 } else { 360 final String message = "The bean is not EJB compliant. " + 365 "The finder method ["+req.getMethodInstance().getName()+"] is declared " + 366 "to return neither Collection nor the Remote Interface, " + 367 "but [" +result.getClass().getName()+ "]"; 368 result = new RemoteException ( message ); 369 this.daemon.logger.error( req + " " + message); 370 res.setResponse( EJB_SYS_EXCEPTION, result); 371 } 372 } 373 374 protected void doEjbObject_GET_EJB_HOME( EJBRequest req, EJBResponse res ) throws Exception { 376 checkMethodAuthorization( req, res ); 377 } 378 379 protected void doEjbObject_GET_HANDLE( EJBRequest req, EJBResponse res ) throws Exception { 380 checkMethodAuthorization( req, res ); 381 } 382 383 protected void doEjbObject_GET_PRIMARY_KEY( EJBRequest req, EJBResponse res ) throws Exception { 384 checkMethodAuthorization( req, res ); 385 } 386 387 protected void doEjbObject_IS_IDENTICAL( EJBRequest req, EJBResponse res ) throws Exception { 388 checkMethodAuthorization( req, res ); 389 } 390 391 protected void doEjbObject_REMOVE( EJBRequest req, EJBResponse res ) throws Exception { 392 393 CallContext call = CallContext.getCallContext(); 394 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 395 396 Object result = c.invoke( req.getDeploymentId(), 397 req.getMethodInstance(), 398 req.getMethodParameters(), 399 req.getPrimaryKey(), 400 req.getClientIdentity()); 401 402 res.setResponse( EJB_OK, null); 403 } 404 405 protected void doEjbHome_GET_EJB_META_DATA( EJBRequest req, EJBResponse res ) throws Exception { 407 checkMethodAuthorization( req, res ); 408 } 409 410 protected void doEjbHome_GET_HOME_HANDLE( EJBRequest req, EJBResponse res ) throws Exception { 411 checkMethodAuthorization( req, res ); 412 } 413 414 protected void doEjbHome_REMOVE_BY_HANDLE( EJBRequest req, EJBResponse res ) throws Exception { 415 416 CallContext call = CallContext.getCallContext(); 417 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 418 419 Object result = c.invoke( req.getDeploymentId(), 420 req.getMethodInstance(), 421 req.getMethodParameters(), 422 req.getPrimaryKey(), 423 req.getClientIdentity()); 424 425 res.setResponse( EJB_OK, null); 426 } 427 428 protected void doEjbHome_REMOVE_BY_PKEY( EJBRequest req, EJBResponse res ) throws Exception { 429 430 CallContext call = CallContext.getCallContext(); 431 RpcContainer c = (RpcContainer)call.getDeploymentInfo().getContainer(); 432 433 Object result = c.invoke( req.getDeploymentId(), 434 req.getMethodInstance(), 435 req.getMethodParameters(), 436 req.getPrimaryKey(), 437 req.getClientIdentity()); 438 439 res.setResponse( EJB_OK, null); 440 } 441 442 protected void checkMethodAuthorization( EJBRequest req, EJBResponse res ) throws Exception { 443 447 SecurityService sec = OpenEJB.getSecurityService(); 448 CallContext caller = CallContext.getCallContext(); 449 DeploymentInfo di = caller.getDeploymentInfo(); 450 String [] authRoles = di.getAuthorizedRoles( req.getMethodInstance() ); 451 452 if (sec.isCallerAuthorized( req.getClientIdentity(), authRoles )) { 453 res.setResponse( EJB_OK, null ); 454 } else { 455 this.daemon.logger.info(req + "Unauthorized Access by Principal Denied"); 456 res.setResponse( EJB_APP_EXCEPTION , new RemoteException ("Unauthorized Access by Principal Denied") ); 457 } 458 } 459 460 private void replyWithFatalError(ObjectOutputStream out,Throwable error,String message) { 461 this.daemon.logger.fatal(message, error); 462 RemoteException re = new RemoteException 463 ("The server has encountered a fatal error: "+message+" "+error); 464 EJBResponse res = new EJBResponse(); 465 res.setResponse(EJB_ERROR, re); 466 try { 467 res.writeExternal(out); 468 } catch (java.io.IOException ie) { 469 this.daemon.logger.error("Failed to write to EJBResponse", ie); 470 } 471 } 472 } 473 | Popular Tags |