1. /*
  2. * @(#)ServerManagerImpl.java 1.48 04/06/21
  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.impl.activation;
  8. /**
  9. *
  10. * @author Rohit Garg
  11. * @author Ken Cavanaugh
  12. * @author Hemanth Puttaswamy
  13. * @since JDK1.2
  14. */
  15. import java.lang.reflect.Constructor;
  16. import java.util.ArrayList;
  17. import java.util.HashMap;
  18. import java.util.Iterator;
  19. import java.util.NoSuchElementException;
  20. import org.omg.CORBA.OBJECT_NOT_EXIST;
  21. import org.omg.CORBA.SystemException;
  22. import com.sun.corba.se.spi.activation.EndPointInfo;
  23. import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
  24. import com.sun.corba.se.spi.activation.ORBPortInfo;
  25. import com.sun.corba.se.spi.activation.Repository;
  26. import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation;
  27. import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB;
  28. import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef;
  29. import com.sun.corba.se.spi.activation._ServerManagerImplBase;
  30. import com.sun.corba.se.spi.activation.ServerAlreadyActive;
  31. import com.sun.corba.se.spi.activation.ServerAlreadyInstalled;
  32. import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled;
  33. import com.sun.corba.se.spi.activation.ServerNotRegistered;
  34. import com.sun.corba.se.spi.activation.ORBAlreadyRegistered;
  35. import com.sun.corba.se.spi.activation.ServerHeldDown;
  36. import com.sun.corba.se.spi.activation.ServerNotActive;
  37. import com.sun.corba.se.spi.activation.NoSuchEndPoint;
  38. import com.sun.corba.se.spi.activation.InvalidORBid;
  39. import com.sun.corba.se.spi.activation.Server;
  40. import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT;
  41. import com.sun.corba.se.spi.ior.IORTemplate ;
  42. import com.sun.corba.se.spi.ior.IOR ;
  43. import com.sun.corba.se.spi.ior.ObjectKey ;
  44. import com.sun.corba.se.spi.ior.ObjectKeyTemplate ;
  45. import com.sun.corba.se.spi.ior.IORFactories ;
  46. import com.sun.corba.se.spi.ior.iiop.GIOPVersion ;
  47. import com.sun.corba.se.spi.ior.iiop.IIOPAddress ;
  48. import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ;
  49. import com.sun.corba.se.spi.ior.iiop.IIOPFactories ;
  50. import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo;
  51. import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor;
  52. import com.sun.corba.se.spi.orb.ORB ;
  53. import com.sun.corba.se.spi.protocol.ForwardException;
  54. import com.sun.corba.se.spi.transport.CorbaTransportManager;
  55. import com.sun.corba.se.spi.logging.CORBALogDomains ;
  56. import com.sun.corba.se.impl.logging.ActivationSystemException ;
  57. import com.sun.corba.se.impl.oa.poa.BadServerIdHandler;
  58. import com.sun.corba.se.impl.orbutil.ORBConstants;
  59. import com.sun.corba.se.impl.orbutil.ORBClassLoader;
  60. import com.sun.corba.se.impl.orbutil.ORBUtility;
  61. import com.sun.corba.se.impl.util.Utility;
  62. public class ServerManagerImpl extends _ServerManagerImplBase
  63. implements BadServerIdHandler
  64. {
  65. // Using HashMap, since synchronization should be done by the calling
  66. // routines
  67. HashMap serverTable;
  68. Repository repository;
  69. CorbaTransportManager transportManager;
  70. int initialPort;
  71. ORB orb;
  72. ActivationSystemException wrapper;
  73. String dbDirName;
  74. boolean debug = false ;
  75. private int serverStartupDelay;
  76. ServerManagerImpl(ORB orb, CorbaTransportManager transportManager,
  77. Repository repository, String dbDirName, boolean debug)
  78. {
  79. this.orb = orb;
  80. wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_ACTIVATOR ) ;
  81. this.transportManager = transportManager; // REVISIT - NOT USED.
  82. this.repository = repository;
  83. this.dbDirName = dbDirName;
  84. this.debug = debug ;
  85. LegacyServerSocketEndPointInfo endpoint =
  86. orb.getLegacyServerSocketManager()
  87. .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING);
  88. initialPort = ((SocketOrChannelAcceptor)endpoint)
  89. .getServerSocket().getLocalPort();
  90. serverTable = new HashMap(256);
  91. // The ServerStartupDelay is the delay added after the Server registers
  92. // end point information. This is to allow the server to completely
  93. // initialize after ORB is instantiated.
  94. serverStartupDelay = ORBConstants.DEFAULT_SERVER_STARTUP_DELAY;
  95. String delay = System.getProperty( ORBConstants.SERVER_STARTUP_DELAY);
  96. if( delay != null ) {
  97. try {
  98. serverStartupDelay = Integer.parseInt( delay );
  99. } catch ( Exception e ) {
  100. // Just use the default 1000 milliseconds as the default
  101. }
  102. }
  103. Class cls = orb.getORBData( ).getBadServerIdHandler();
  104. if( cls == null ) {
  105. orb.setBadServerIdHandler( this );
  106. } else {
  107. orb.initBadServerIdHandler() ;
  108. }
  109. orb.connect(this);
  110. ProcessMonitorThread.start( serverTable );
  111. }
  112. public void activate(int serverId)
  113. throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown
  114. {
  115. ServerLocation location;
  116. ServerTableEntry entry;
  117. Integer key = new Integer(serverId);
  118. synchronized(serverTable) {
  119. entry = (ServerTableEntry) serverTable.get(key);
  120. }
  121. if (entry != null && entry.isActive()) {
  122. if (debug)
  123. System.out.println( "ServerManagerImpl: activate for server Id " +
  124. serverId + " failed because server is already active. " +
  125. "entry = " + entry ) ;
  126. throw new ServerAlreadyActive( serverId );
  127. }
  128. // locate the server
  129. try {
  130. // We call getEntry here so that state of the entry is
  131. // checked for validity before we actually go and locate a server
  132. entry = getEntry(serverId);
  133. if (debug)
  134. System.out.println( "ServerManagerImpl: locateServer called with " +
  135. " serverId=" + serverId + " endpointType="
  136. + IIOP_CLEAR_TEXT.value + " block=false" ) ;
  137. location = locateServer(entry, IIOP_CLEAR_TEXT.value, false);
  138. if (debug)
  139. System.out.println( "ServerManagerImpl: activate for server Id " +
  140. serverId + " found location " +
  141. location.hostname + " and activated it" ) ;
  142. } catch (NoSuchEndPoint ex) {
  143. if (debug)
  144. System.out.println( "ServerManagerImpl: activate for server Id " +
  145. " threw NoSuchEndpoint exception, which was ignored" );
  146. }
  147. }
  148. public void active(int serverId, Server server) throws ServerNotRegistered
  149. {
  150. ServerTableEntry entry;
  151. Integer key = new Integer(serverId);
  152. synchronized (serverTable) {
  153. entry = (ServerTableEntry) serverTable.get(key);
  154. if (entry == null) {
  155. if (debug)
  156. System.out.println( "ServerManagerImpl: active for server Id " +
  157. serverId + " called, but no such server is registered." ) ;
  158. throw wrapper.serverNotExpectedToRegister() ;
  159. } else {
  160. if (debug)
  161. System.out.println( "ServerManagerImpl: active for server Id " +
  162. serverId + " called. This server is now active." ) ;
  163. entry.register(server);
  164. }
  165. }
  166. }
  167. public void registerEndpoints( int serverId, String orbId,
  168. EndPointInfo [] endpointList ) throws NoSuchEndPoint, ServerNotRegistered,
  169. ORBAlreadyRegistered
  170. {
  171. // orbId is ignored for now
  172. ServerTableEntry entry;
  173. Integer key = new Integer(serverId);
  174. synchronized (serverTable) {
  175. entry = (ServerTableEntry) serverTable.get(key);
  176. if (entry == null) {
  177. if (debug)
  178. System.out.println(
  179. "ServerManagerImpl: registerEndpoint for server Id " +
  180. serverId + " called, but no such server is registered." ) ;
  181. throw wrapper.serverNotExpectedToRegister() ;
  182. } else {
  183. if (debug)
  184. System.out.println(
  185. "ServerManagerImpl: registerEndpoints for server Id " +
  186. serverId + " called. This server is now active." ) ;
  187. entry.registerPorts( orbId, endpointList );
  188. }
  189. }
  190. }
  191. public int[] getActiveServers()
  192. {
  193. ServerTableEntry entry;
  194. int[] list = null;
  195. synchronized (serverTable) {
  196. // unlike vectors, list is not synchronized
  197. ArrayList servers = new ArrayList(0);
  198. Iterator serverList = serverTable.keySet().iterator();
  199. try {
  200. while (serverList.hasNext()) {
  201. Integer key = (Integer) serverList.next();
  202. // get an entry
  203. entry = (ServerTableEntry) serverTable.get(key);
  204. if (entry.isValid() && entry.isActive()) {
  205. servers.add(entry);
  206. }
  207. }
  208. } catch (NoSuchElementException e) {
  209. // all done
  210. }
  211. // collect the active entries
  212. list = new int[servers.size()];
  213. for (int i = 0; i < servers.size(); i++) {
  214. entry = (ServerTableEntry) servers.get(i);
  215. list[i] = entry.getServerId();
  216. }
  217. }
  218. if (debug) {
  219. StringBuffer sb = new StringBuffer() ;
  220. for (int ctr=0; ctr<list.length; ctr++) {
  221. sb.append( ' ' ) ;
  222. sb.append( list[ctr] ) ;
  223. }
  224. System.out.println( "ServerManagerImpl: getActiveServers returns" +
  225. sb.toString() ) ;
  226. }
  227. return list;
  228. }
  229. public void shutdown(int serverId) throws ServerNotActive
  230. {
  231. ServerTableEntry entry;
  232. Integer key = new Integer(serverId);
  233. synchronized(serverTable) {
  234. entry = (ServerTableEntry) serverTable.remove(key);
  235. if (entry == null) {
  236. if (debug)
  237. System.out.println( "ServerManagerImpl: shutdown for server Id " +
  238. serverId + " throws ServerNotActive." ) ;
  239. throw new ServerNotActive( serverId );
  240. }
  241. try {
  242. entry.destroy();
  243. if (debug)
  244. System.out.println( "ServerManagerImpl: shutdown for server Id " +
  245. serverId + " completed." ) ;
  246. } catch (Exception e) {
  247. if (debug)
  248. System.out.println( "ServerManagerImpl: shutdown for server Id " +
  249. serverId + " threw exception " + e ) ;
  250. }
  251. }
  252. }
  253. private ServerTableEntry getEntry( int serverId )
  254. throws ServerNotRegistered
  255. {
  256. Integer key = new Integer(serverId);
  257. ServerTableEntry entry = null ;
  258. synchronized (serverTable) {
  259. entry = (ServerTableEntry) serverTable.get(key);
  260. if (debug)
  261. if (entry == null) {
  262. System.out.println( "ServerManagerImpl: getEntry: " +
  263. "no active server found." ) ;
  264. } else {
  265. System.out.println( "ServerManagerImpl: getEntry: " +
  266. " active server found " + entry + "." ) ;
  267. }
  268. if ((entry != null) && (!entry.isValid())) {
  269. serverTable.remove(key);
  270. entry = null;
  271. }
  272. if (entry == null) {
  273. ServerDef serverDef = repository.getServer(serverId);
  274. entry = new ServerTableEntry( wrapper,
  275. serverId, serverDef, initialPort, dbDirName, false, debug);
  276. serverTable.put(key, entry);
  277. entry.activate() ;
  278. }
  279. }
  280. return entry ;
  281. }
  282. private ServerLocation locateServer (ServerTableEntry entry, String endpointType,
  283. boolean block)
  284. throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
  285. {
  286. ServerLocation location = new ServerLocation() ;
  287. // if server location is desired, then wait for the server
  288. // to register back, then return location
  289. ORBPortInfo [] serverORBAndPortList;
  290. if (block) {
  291. try {
  292. serverORBAndPortList = entry.lookup(endpointType);
  293. } catch (Exception ex) {
  294. if (debug)
  295. System.out.println( "ServerManagerImpl: locateServer: " +
  296. "server held down" ) ;
  297. throw new ServerHeldDown( entry.getServerId() );
  298. }
  299. String host =
  300. orb.getLegacyServerSocketManager()
  301. .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
  302. location.hostname = host ;
  303. int listLength;
  304. if (serverORBAndPortList != null) {
  305. listLength = serverORBAndPortList.length;
  306. } else {
  307. listLength = 0;
  308. }
  309. location.ports = new ORBPortInfo[listLength];
  310. for (int i = 0; i < listLength; i++) {
  311. location.ports[i] = new ORBPortInfo(serverORBAndPortList[i].orbId,
  312. serverORBAndPortList[i].port) ;
  313. if (debug)
  314. System.out.println( "ServerManagerImpl: locateServer: " +
  315. "server located at location " +
  316. location.hostname + " ORBid " +
  317. serverORBAndPortList[i].orbId +
  318. " Port " + serverORBAndPortList[i].port) ;
  319. }
  320. }
  321. return location;
  322. }
  323. private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId,
  324. boolean block)
  325. throws InvalidORBid, ServerNotRegistered, ServerHeldDown
  326. {
  327. ServerLocationPerORB location = new ServerLocationPerORB() ;
  328. // if server location is desired, then wait for the server
  329. // to register back, then return location
  330. EndPointInfo [] endpointInfoList;
  331. if (block) {
  332. try {
  333. endpointInfoList = entry.lookupForORB(orbId);
  334. } catch (InvalidORBid ex) {
  335. throw ex;
  336. } catch (Exception ex) {
  337. if (debug)
  338. System.out.println( "ServerManagerImpl: locateServerForORB: " +
  339. "server held down" ) ;
  340. throw new ServerHeldDown( entry.getServerId() );
  341. }
  342. String host =
  343. orb.getLegacyServerSocketManager()
  344. .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName();
  345. location.hostname = host ;
  346. int listLength;
  347. if (endpointInfoList != null) {
  348. listLength = endpointInfoList.length;
  349. } else {
  350. listLength = 0;
  351. }
  352. location.ports = new EndPointInfo[listLength];
  353. for (int i = 0; i < listLength; i++) {
  354. location.ports[i] = new EndPointInfo(endpointInfoList[i].endpointType,
  355. endpointInfoList[i].port) ;
  356. if (debug)
  357. System.out.println( "ServerManagerImpl: locateServer: " +
  358. "server located at location " +
  359. location.hostname + " endpointType " +
  360. endpointInfoList[i].endpointType +
  361. " Port " + endpointInfoList[i].port) ;
  362. }
  363. }
  364. return location;
  365. }
  366. public String[] getORBNames(int serverId)
  367. throws ServerNotRegistered
  368. {
  369. try {
  370. ServerTableEntry entry = getEntry( serverId ) ;
  371. return (entry.getORBList());
  372. } catch (Exception ex) {
  373. throw new ServerNotRegistered(serverId);
  374. }
  375. }
  376. private ServerTableEntry getRunningEntry( int serverId )
  377. throws ServerNotRegistered
  378. {
  379. ServerTableEntry entry = getEntry( serverId ) ;
  380. try {
  381. // this is to see if the server has any listeners
  382. ORBPortInfo [] serverORBAndPortList = entry.lookup(IIOP_CLEAR_TEXT.value) ;
  383. } catch (Exception exc) {
  384. return null ;
  385. }
  386. return entry;
  387. }
  388. public void install( int serverId )
  389. throws ServerNotRegistered, ServerHeldDown, ServerAlreadyInstalled
  390. {
  391. ServerTableEntry entry = getRunningEntry( serverId ) ;
  392. if (entry != null) {
  393. repository.install( serverId ) ;
  394. entry.install() ;
  395. }
  396. }
  397. public void uninstall( int serverId )
  398. throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled
  399. {
  400. ServerTableEntry entry =
  401. (ServerTableEntry) serverTable.get( new Integer(serverId) );
  402. if (entry != null) {
  403. entry =
  404. (ServerTableEntry) serverTable.remove(new Integer(serverId));
  405. if (entry == null) {
  406. if (debug)
  407. System.out.println( "ServerManagerImpl: shutdown for server Id " +
  408. serverId + " throws ServerNotActive." ) ;
  409. throw new ServerHeldDown( serverId );
  410. }
  411. entry.uninstall();
  412. }
  413. }
  414. public ServerLocation locateServer (int serverId, String endpointType)
  415. throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown
  416. {
  417. ServerTableEntry entry = getEntry( serverId ) ;
  418. if (debug)
  419. System.out.println( "ServerManagerImpl: locateServer called with " +
  420. " serverId=" + serverId + " endpointType=" +
  421. endpointType + " block=true" ) ;
  422. // passing in entry to eliminate multiple lookups for
  423. // the same entry in some cases
  424. return locateServer(entry, endpointType, true);
  425. }
  426. /** This method is used to obtain the registered ports for an ORB.
  427. * This is useful for custom Bad server ID handlers in ORBD.
  428. */
  429. public ServerLocationPerORB locateServerForORB (int serverId, String orbId)
  430. throws InvalidORBid, ServerNotRegistered, ServerHeldDown
  431. {
  432. ServerTableEntry entry = getEntry( serverId ) ;
  433. // passing in entry to eliminate multiple lookups for
  434. // the same entry in some cases
  435. if (debug)
  436. System.out.println( "ServerManagerImpl: locateServerForORB called with " +
  437. " serverId=" + serverId + " orbId=" + orbId +
  438. " block=true" ) ;
  439. return locateServerForORB(entry, orbId, true);
  440. }
  441. public void handle(ObjectKey okey)
  442. {
  443. IOR newIOR = null;
  444. ServerLocationPerORB location;
  445. // we need to get the serverid and the orbid from the object key
  446. ObjectKeyTemplate oktemp = okey.getTemplate();
  447. int serverId = oktemp.getServerId() ;
  448. String orbId = oktemp.getORBId() ;
  449. try {
  450. // get the ORBName corresponding to the orbMapid, that was
  451. // first registered by the server
  452. ServerTableEntry entry = getEntry( serverId ) ;
  453. location = locateServerForORB(entry, orbId, true);
  454. if (debug)
  455. System.out.println( "ServerManagerImpl: handle called for server id" +
  456. serverId + " orbid " + orbId) ;
  457. // we received a list of ports corresponding to an ORB in a
  458. // particular server, now retrieve the one corresponding
  459. // to IIOP_CLEAR_TEXT, and for other created the tagged
  460. // components to be added to the IOR
  461. int clearPort = 0;
  462. EndPointInfo[] listenerPorts = location.ports;
  463. for (int i = 0; i < listenerPorts.length; i++) {
  464. if ((listenerPorts[i].endpointType).equals(IIOP_CLEAR_TEXT.value)) {
  465. clearPort = listenerPorts[i].port;
  466. break;
  467. }
  468. }
  469. // create a new IOR with the correct port and correct tagged
  470. // components
  471. IIOPAddress addr = IIOPFactories.makeIIOPAddress( orb,
  472. location.hostname, clearPort ) ;
  473. IIOPProfileTemplate iptemp =
  474. IIOPFactories.makeIIOPProfileTemplate(
  475. orb, GIOPVersion.V1_2, addr ) ;
  476. if (GIOPVersion.V1_2.supportsIORIIOPProfileComponents()) {
  477. iptemp.add(IIOPFactories.makeCodeSetsComponent(orb));
  478. iptemp.add(IIOPFactories.makeMaxStreamFormatVersionComponent());
  479. }
  480. IORTemplate iortemp = IORFactories.makeIORTemplate(oktemp) ;
  481. iortemp.add( iptemp ) ;
  482. newIOR = iortemp.makeIOR(orb, "IDL:org/omg/CORBA/Object:1.0",
  483. okey.getId() );
  484. } catch (Exception e) {
  485. throw wrapper.errorInBadServerIdHandler( e ) ;
  486. }
  487. if (debug)
  488. System.out.println( "ServerManagerImpl: handle " +
  489. "throws ForwardException" ) ;
  490. try {
  491. // This delay is required in case of Server is activated or
  492. // re-activated the first time. Server needs some time before
  493. // handling all the requests.
  494. // (Talk to Ken to see whether there is a better way of doing this).
  495. Thread.sleep( serverStartupDelay );
  496. } catch ( Exception e ) {
  497. System.out.println( "Exception = " + e );
  498. e.printStackTrace();
  499. }
  500. throw new ForwardException(orb, newIOR);
  501. }
  502. public int getEndpoint(String endpointType) throws NoSuchEndPoint
  503. {
  504. return orb.getLegacyServerSocketManager()
  505. .legacyGetTransientServerPort(endpointType);
  506. }
  507. public int getServerPortForType(ServerLocationPerORB location,
  508. String endPointType)
  509. throws NoSuchEndPoint
  510. {
  511. EndPointInfo[] listenerPorts = location.ports;
  512. for (int i = 0; i < listenerPorts.length; i++) {
  513. if ((listenerPorts[i].endpointType).equals(endPointType)) {
  514. return listenerPorts[i].port;
  515. }
  516. }
  517. throw new NoSuchEndPoint();
  518. }
  519. }