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