1. /*
  2. * @(#)RequestProcessor.java 1.20 03/01/23
  3. *
  4. * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. /*
  8. * Licensed Materials - Property of IBM
  9. * RMI-IIOP v1.0
  10. * Copyright IBM Corp. 1998 1999 All Rights Reserved
  11. *
  12. * US Government Users Restricted Rights - Use, duplication or
  13. * disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  14. */
  15. package com.sun.corba.se.internal.iiop;
  16. import org.omg.CORBA.SystemException;
  17. import org.omg.CORBA.TRANSIENT;
  18. import org.omg.CORBA.UNKNOWN;
  19. import org.omg.CORBA.CompletionStatus;
  20. import com.sun.corba.se.internal.core.RequestHandler;
  21. import com.sun.corba.se.internal.core.IOR;
  22. import com.sun.corba.se.internal.core.ServerRequest;
  23. import com.sun.corba.se.internal.orbutil.MinorCodes;
  24. import com.sun.corba.se.internal.core.GIOPVersion;
  25. import com.sun.corba.se.internal.orbutil.Work;
  26. import com.sun.corba.se.internal.iiop.messages.*;
  27. /**
  28. * Replaces CachedWorkerThread -- handles Requests and LocateRequests, and can
  29. * be run in a pooled thread.
  30. */
  31. final class RequestProcessor implements Work
  32. {
  33. private static final String name = "RequestProcessor";
  34. private RequestHandler handler;
  35. private IIOPConnection conn;
  36. private IIOPInputStream request;
  37. RequestProcessor(RequestHandler h, IIOPConnection c, IIOPInputStream is) {
  38. handler = h;
  39. conn = c;
  40. request = is;
  41. }
  42. public final String getName() {
  43. return name;
  44. }
  45. public void process()
  46. {
  47. IIOPOutputStream response = null;
  48. Message msg = request.getMessage();
  49. ORB orb = conn.getORB() ;
  50. conn.requestBegins();
  51. try {
  52. switch (msg.getType()) {
  53. case Message.GIOPRequest: {
  54. ServerRequest srequest = (ServerRequest)request;
  55. try {
  56. // Doesn't do anything if the header was already
  57. // unmarshaled
  58. request.unmarshalHeader();
  59. // Here is the actual dispatch to the ORB which
  60. // dispatches to the subcontract which dispatches to the
  61. // skeleton which finally dispatches to the user's servant.
  62. response = (IIOPOutputStream)handler.process(srequest);
  63. if (srequest.isOneWay()) {
  64. return;
  65. }
  66. } catch (SystemException ex) {
  67. // If we haven't unmarshaled the header, we probably don't
  68. // have enough information to even send back a reply.
  69. // REVISIT
  70. if (!request.unmarshaledHeader())
  71. return;
  72. // Caught a system exception marshal it back to the client
  73. //
  74. // ex.printStackTrace();
  75. // conn.dprint("run: got exception: " + ex);
  76. // Shouldn't we send back the service contexts?? REVISIT
  77. try {
  78. response = (IIOPOutputStream)
  79. srequest.createSystemExceptionResponse(ex, null);
  80. } catch (Exception e) {
  81. return; // marshaling exception error; return;
  82. }
  83. } catch (AddressingDispositionException ex) {
  84. // create a response containing the expected target
  85. // addressing disposition.
  86. RequestMessage rmsg = (RequestMessage) msg;
  87. int requestId = rmsg.getRequestId();
  88. ReplyMessage replyMsg = MessageBase.createReply(
  89. orb, rmsg.getGIOPVersion(),
  90. rmsg.getRequestId(),
  91. ReplyMessage.NEEDS_ADDRESSING_MODE,
  92. null, null);
  93. response = new IIOPOutputStream(
  94. request.getGIOPVersion(),
  95. request.getConnection().getORB(),
  96. request.getConnection());
  97. response.setMessage(replyMsg);
  98. replyMsg.write(response);
  99. AddressingDispositionHelper.write(
  100. response, ex.expectedAddrDisp());
  101. } catch (RequestCanceledException ex) {
  102. // Creating an exception response causes the
  103. // poa current stack, the interceptor stacks, etc.
  104. // to be balanced. It also notifies interceptors
  105. // that the request was cancelled.
  106. SystemException sex =
  107. new TRANSIENT("RequestCanceled",
  108. MinorCodes.REQUEST_CANCELED,
  109. CompletionStatus.COMPLETED_NO);
  110. srequest.createSystemExceptionResponse(sex, null);
  111. // NOTE: the response stream is not returned.
  112. // It is only created for its side-effects.
  113. // The worker thread can now process further requests.
  114. return;
  115. } catch (Throwable ex) {
  116. // NOTE: We do not trap ThreadDeath above Throwable.
  117. // There is no reason to stop the thread. It is
  118. // just a worker thread. The ORB never throws
  119. // ThreadDeath. Client code may (e.g., in ServantManagers,
  120. // interceptors, or servants) but that should not
  121. // effect the ORB threads. So it is just handled
  122. // generically.
  123. //
  124. // Caught an unknown Exception or Error, create a
  125. // SystemException and marshal it back to the client
  126. //
  127. // conn.dprint("run: got exception: " + ex);
  128. // ex.printStackTrace();
  129. // If we haven't unmarshaled the header, we probably don't
  130. // have enough information to even send back a reply.
  131. // REVISIT (send closeconnection)
  132. if (!request.unmarshaledHeader())
  133. return;
  134. SystemException exc = new UNKNOWN(MinorCodes.UNKNOWN_SERVER_ERROR,
  135. CompletionStatus.COMPLETED_MAYBE);
  136. try {
  137. response = (IIOPOutputStream)
  138. srequest.createSystemExceptionResponse(exc, null);
  139. } catch (Exception e) {
  140. return; // marshaling exception error; return;
  141. }
  142. }
  143. break;
  144. }
  145. case Message.GIOPLocateRequest: {
  146. LocateRequestMessage lmsg = null;
  147. LocateReplyMessage reply = null;
  148. int requestId = -1;
  149. GIOPVersion giopVersion = null;
  150. IOR ior = null;
  151. short addrDisp = -1;
  152. try {
  153. request.unmarshalHeader();
  154. lmsg = (LocateRequestMessage) msg;
  155. requestId = lmsg.getRequestId();
  156. giopVersion = lmsg.getGIOPVersion();
  157. ior = handler.locate(lmsg.getObjectKey());
  158. if ( ior == null ) {
  159. reply = MessageBase.createLocateReply(
  160. orb, giopVersion, requestId,
  161. LocateReplyMessage.OBJECT_HERE, null);
  162. } else {
  163. reply = MessageBase.createLocateReply(
  164. orb, giopVersion, requestId,
  165. LocateReplyMessage.OBJECT_FORWARD, ior);
  166. }
  167. // Shouldn't we also catch SystemExceptions as above? REVISIT
  168. } catch (AddressingDispositionException ex) {
  169. // create a response containing the expected target
  170. // addressing disposition.
  171. lmsg = (LocateRequestMessage) msg;
  172. requestId = lmsg.getRequestId();
  173. giopVersion = lmsg.getGIOPVersion();
  174. reply = MessageBase.createLocateReply(
  175. orb, giopVersion,
  176. requestId,
  177. LocateReplyMessage.LOC_NEEDS_ADDRESSING_MODE,
  178. null);
  179. addrDisp = ex.expectedAddrDisp();
  180. } catch (RequestCanceledException ex) {
  181. return; // no need to send reply
  182. } catch ( Exception ex ) {
  183. // REVISIT If exception is not OBJECT_NOT_EXIST, it should
  184. // have a different reply
  185. // This handles OBJECT_NOT_EXIST exceptions thrown in
  186. // the subcontract or obj manager. Send back UNKNOWN_OBJECT.
  187. reply = MessageBase.createLocateReply(
  188. orb, giopVersion, requestId,
  189. LocateReplyMessage.UNKNOWN_OBJECT, null);
  190. }
  191. // This chooses the right buffering strategy for the locate msg.
  192. // locate msgs 1.0 & 1.1 :=> grow, 1.2 :=> stream
  193. response = IIOPOutputStream.createIIOPOutputStreamForLocateMsg(
  194. giopVersion, request.getConnection().getORB(),
  195. request.getConnection());
  196. reply.write(response);
  197. response.setMessage(reply);
  198. if (ior != null) {
  199. ior.write(response);
  200. }
  201. if (addrDisp != -1) {
  202. AddressingDispositionHelper.write(response, addrDisp);
  203. }
  204. break;
  205. }
  206. default:
  207. //
  208. // Any other message type is unexpected and is a fatal
  209. // error for this connection ??
  210. //
  211. return;
  212. } // end switch (msgType)
  213. // Send the reply on the wire
  214. // Only RequestMessages and LocateRequestMessages have replies
  215. conn.sendReply(response);
  216. } catch(Exception e) {
  217. // REVISIT This block should catch Throwable
  218. // and possibly do close connection processing.
  219. // Most likely it should do an assert since we should not
  220. // ever make it here.
  221. } finally {
  222. conn.requestEnds(request);
  223. }
  224. }
  225. }