1. /*
  2. * @(#)GIOPImpl.java 1.51 04/01/13
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package com.sun.corba.se.internal.iiop;
  8. import java.net.ServerSocket ;
  9. import java.util.Collection ;
  10. import java.util.HashMap ;
  11. import java.util.Vector ;
  12. import java.util.Iterator ;
  13. import java.util.Enumeration ;
  14. import java.util.Map ;
  15. import com.sun.corba.se.internal.core.ClientGIOP;
  16. import com.sun.corba.se.internal.core.ServerGIOP;
  17. import com.sun.corba.se.internal.core.IOR;
  18. import com.sun.corba.se.internal.core.RequestHandler;
  19. import com.sun.corba.se.internal.core.ServiceContext;
  20. import com.sun.corba.se.internal.core.ServiceContexts;
  21. import com.sun.corba.se.internal.core.ClientRequest;
  22. import com.sun.corba.se.internal.core.EndPoint;
  23. import com.sun.corba.se.internal.corba.ClientDelegate;
  24. import com.sun.corba.se.internal.corba.EncapsOutputStream;
  25. import com.sun.corba.se.internal.orbutil.ORBUtility;
  26. import com.sun.corba.se.internal.ior.IIOPProfile ;
  27. import com.sun.corba.se.internal.ior.ObjectKeyTemplate;
  28. import com.sun.corba.se.internal.ior.ObjectId ;
  29. import org.omg.CORBA.INITIALIZE;
  30. import org.omg.CORBA.INTERNAL;
  31. import org.omg.CORBA.CompletionStatus;
  32. import com.sun.corba.se.internal.orbutil.MinorCodes; //d11638
  33. import java.net.InetAddress;
  34. import java.security.AccessController;
  35. import java.security.PrivilegedAction;
  36. public class GIOPImpl implements ClientGIOP, ServerGIOP {
  37. // Start at some value other than zero since this is a magic
  38. // value in some protocols.
  39. private int requestId = 5;
  40. protected synchronized int getNextRequestId() {
  41. return requestId++;
  42. }
  43. protected ConnectionTable table;
  44. protected ORB orb;
  45. public GIOPImpl(ORB orb, RequestHandler handler) {
  46. this.orb = orb;
  47. this.table = new ConnectionTable(orb, this);
  48. setRequestHandler(handler);
  49. }
  50. public Connection getConnection( IOR ior ) {
  51. return table.getConnection( ior ) ;
  52. }
  53. public void deleteConnection( EndPoint ep )
  54. {
  55. try {
  56. table.deleteConn( ep ) ;
  57. } catch( Exception e ) {
  58. // Ignore the exception
  59. }
  60. }
  61. /**
  62. * Allocate a new request id.
  63. */
  64. public int allocateRequestId()
  65. {
  66. return getNextRequestId();
  67. }
  68. private RequestHandler handler;
  69. public void setRequestHandler(RequestHandler handler) {
  70. this.handler = handler;
  71. }
  72. public RequestHandler getRequestHandler() {
  73. return handler;
  74. }
  75. public IOR locate(IOR ior)
  76. {
  77. IIOPProfile iop = ior.getProfile();
  78. ObjectKeyTemplate oktemp = iop.getTemplate().getObjectKeyTemplate() ;
  79. ObjectId oid = iop.getObjectId() ;
  80. EncapsOutputStream os = new EncapsOutputStream( orb ) ;
  81. oktemp.write( oid, os ) ;
  82. byte[] objKey = os.toByteArray() ;
  83. Connection c = table.getConnection(ior);
  84. IOR newIOR = c.locate(getNextRequestId(), objKey, ior);
  85. if ( newIOR == null ) // we got an OBJECT_HERE reply
  86. newIOR = ior;
  87. return newIOR;
  88. }
  89. /****************************************************************************
  90. The following methods are implementations of the ServerGIOP's endpoint APIs.
  91. ****************************************************************************/
  92. protected HashMap listenerThreads = new HashMap();
  93. protected Vector endPoints = new Vector();
  94. private EndPoint bootstrapEndpoint;
  95. private boolean wasExplicitInitializationDone = false;
  96. public synchronized void initEndpoints() {
  97. if (! wasExplicitInitializationDone) {
  98. // REVISIT - temporary until getDefaultEndpoint problem fixed.
  99. if (endPoints.size() == 0) {
  100. // Allocate the default listener.
  101. getEndpoint(EndPoint.IIOP_CLEAR_TEXT, 0, null);
  102. }
  103. // Allocate user listeners.
  104. Iterator types = orb.getUserSpecifiedListenPorts().iterator();
  105. while (types.hasNext()) {
  106. ORB.UserSpecifiedListenPort user =
  107. (ORB.UserSpecifiedListenPort) types.next();
  108. getEndpoint(user.getType(), user.getPort(), null);
  109. }
  110. wasExplicitInitializationDone = true;
  111. }
  112. }
  113. public synchronized EndPoint getDefaultEndpoint() {
  114. // REVISIT - do not depend on order.
  115. // Note: some places in the code just do getEndpoint
  116. // without calling initEndpoint. THis causes the endPoints
  117. // vector to contain entries. They may depend on their
  118. // first call to getEndpoint creating what will become
  119. // the "default" endpoint.
  120. // E.G.: POAORB.setPersistentServerPort
  121. if (endPoints.size() == 0)
  122. return null;
  123. return (EndPoint) endPoints.elementAt(0);
  124. }
  125. /**
  126. * Get an EndPoint for the specified type, listenPort and local address.
  127. *
  128. * Type must be one which has a socket factory
  129. * (e.g., EndPoint.IIOP_CLEAR_TEXT default or user supplied "SSL").
  130. *
  131. * If listenPort == 0, a listening port will be assigned.
  132. *
  133. * If addr == null, InetAddress.getLocalHost() is used.
  134. *
  135. * If an EndPoint at the specified port/address does not exist,
  136. * then it will be created.
  137. */
  138. public synchronized EndPoint getEndpoint(String socketType, int port,
  139. InetAddress addr)
  140. {
  141. if (orb.transportDebugFlag) {
  142. ORBUtility.dprint(this, "getEndpoint(" + socketType + ", " + port + ", " + addr +")");
  143. }
  144. // Check if this endpoint was already created
  145. String host = null;
  146. if (addr != null)
  147. host = addr.getHostName().toLowerCase();
  148. Enumeration eps = endPoints.elements();
  149. while ( eps.hasMoreElements() ) {
  150. EndPoint ep = (EndPoint)eps.nextElement();
  151. if ( ep.getType().equals(socketType) &&
  152. ep.getPort() == port &&
  153. ep.getHostName().equals(host) )
  154. {
  155. return ep;
  156. }
  157. }
  158. // REVISIT - This needs to go in initEndpoints.
  159. // However, it seems getEndpoint may be called before
  160. // init, so it is left here for now.
  161. if (socketType == EndPoint.IIOP_CLEAR_TEXT &&
  162. port == 0 &&
  163. orb.getORBServerPort() != 0)
  164. {
  165. port = orb.getORBServerPort();
  166. }
  167. // Create the endpoint
  168. ListenerThread listenerThread = createListener(socketType, port);
  169. listenerThreads.put(socketType, listenerThread);
  170. EndPoint ep =
  171. new EndPointImpl(socketType,
  172. listenerThread.getSocket().getLocalPort(),
  173. orb.getORBServerHost());
  174. endPoints.addElement(ep);
  175. return ep;
  176. }
  177. /**
  178. * Get an EndPoint for the bootstrap naming service, at the specified port.
  179. * If listenPort == 0 and this is the first time getBootstrapEndpoint was
  180. * invoked, then an EndPoint at the default port of 900 will be created.
  181. * If listenPort == 0 and this is not the first time getBootstrapEndpoint
  182. * was called, then the existing bootstrap EndPoint will be returned.
  183. */
  184. public synchronized EndPoint getBootstrapEndpoint(int port)
  185. {
  186. if (bootstrapEndpoint == null)
  187. bootstrapEndpoint =
  188. getEndpoint(EndPoint.IIOP_CLEAR_TEXT, port, null);
  189. return bootstrapEndpoint;
  190. }
  191. private synchronized ListenerThread createListener(final String socketType,
  192. final int port) {
  193. final ServerSocket ss;
  194. ListenerThread lis;
  195. final ConnectionTable finalTable = table;
  196. if (orb.transportDebugFlag)
  197. ORBUtility.dprint( this, "createListener( socketType = " + socketType +
  198. " port = " + port + " )" ) ;
  199. try {
  200. ss = orb.getSocketFactory().createServerSocket(socketType, port);
  201. lis = (ListenerThread) AccessController.doPrivileged(new PrivilegedAction() {
  202. public java.lang.Object run() {
  203. ListenerThread thread = new ListenerThread(finalTable,
  204. orb.threadGroup,
  205. ss,
  206. socketType);
  207. thread.setDaemon(true);
  208. return thread;
  209. }
  210. });
  211. lis.start();
  212. }
  213. catch (java.lang.Exception e) {
  214. throw new INTERNAL(MinorCodes.CREATE_LISTENER_FAILED,
  215. CompletionStatus.COMPLETED_NO);
  216. }
  217. return lis;
  218. }
  219. public int getServerPort (String socketType)
  220. {
  221. return getServerPort(socketType, false);
  222. }
  223. public int getPersistentServerPort (String socketType)
  224. {
  225. return getServerPort(socketType, true);
  226. }
  227. private int getServerPort (String socketType, boolean isPersistent)
  228. {
  229. if (endPoints.size() == 0) {
  230. throw new INITIALIZE(
  231. "GIOPImpl.get*ServerPort called before endpoints initialized.",
  232. MinorCodes.GET_SERVER_PORT_CALLED_BEFORE_ENDPOINTS_INITIALIZED,
  233. CompletionStatus.COMPLETED_NO);
  234. }
  235. Iterator endpoints = endPoints.iterator();
  236. while (endpoints.hasNext()) {
  237. EndPoint ep = (EndPoint) endpoints.next();
  238. if (ep.getType().equals(socketType)) {
  239. if (isPersistent) {
  240. return ep.getLocatorPort();
  241. } else {
  242. return ep.getPort();
  243. }
  244. }
  245. }
  246. return -1;
  247. }
  248. public Collection getServerEndpoints ()
  249. {
  250. return endPoints;
  251. }
  252. void destroyConnections()
  253. {
  254. // Shut down all Listeners
  255. Iterator threads = listenerThreads.entrySet().iterator();
  256. while (threads.hasNext()) {
  257. // Listener threads always shut down gracefully.
  258. ((ListenerThread)((Map.Entry)threads.next()).getValue()).shutdown();
  259. }
  260. // Shut down all Readers
  261. table.destroyConnections();
  262. }
  263. }