/* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.sun.corba.se.impl.activation; /** * * @author Rohit Garg * @author Ken Cavanaugh * @author Hemanth Puttaswamy * @since JDK1.2 */ import java.lang.reflect.Constructor; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.NoSuchElementException; import org.omg.CORBA.OBJECT_NOT_EXIST; import org.omg.CORBA.SystemException; import com.sun.corba.se.spi.activation.EndPointInfo; import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT; import com.sun.corba.se.spi.activation.ORBPortInfo; import com.sun.corba.se.spi.activation.Repository; import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocation; import com.sun.corba.se.spi.activation.LocatorPackage.ServerLocationPerORB; import com.sun.corba.se.spi.activation.RepositoryPackage.ServerDef; import com.sun.corba.se.spi.activation._ServerManagerImplBase; import com.sun.corba.se.spi.activation.ServerAlreadyActive; import com.sun.corba.se.spi.activation.ServerAlreadyInstalled; import com.sun.corba.se.spi.activation.ServerAlreadyUninstalled; import com.sun.corba.se.spi.activation.ServerNotRegistered; import com.sun.corba.se.spi.activation.ORBAlreadyRegistered; import com.sun.corba.se.spi.activation.ServerHeldDown; import com.sun.corba.se.spi.activation.ServerNotActive; import com.sun.corba.se.spi.activation.NoSuchEndPoint; import com.sun.corba.se.spi.activation.InvalidORBid; import com.sun.corba.se.spi.activation.Server; import com.sun.corba.se.spi.activation.IIOP_CLEAR_TEXT; import com.sun.corba.se.spi.ior.IORTemplate ; import com.sun.corba.se.spi.ior.IOR ; import com.sun.corba.se.spi.ior.ObjectKey ; import com.sun.corba.se.spi.ior.ObjectKeyTemplate ; import com.sun.corba.se.spi.ior.IORFactories ; import com.sun.corba.se.spi.ior.iiop.GIOPVersion ; import com.sun.corba.se.spi.ior.iiop.IIOPAddress ; import com.sun.corba.se.spi.ior.iiop.IIOPProfileTemplate ; import com.sun.corba.se.spi.ior.iiop.IIOPFactories ; import com.sun.corba.se.spi.legacy.connection.LegacyServerSocketEndPointInfo; import com.sun.corba.se.spi.transport.SocketOrChannelAcceptor; import com.sun.corba.se.spi.orb.ORB ; import com.sun.corba.se.spi.protocol.ForwardException; import com.sun.corba.se.spi.transport.CorbaTransportManager; import com.sun.corba.se.spi.logging.CORBALogDomains ; import com.sun.corba.se.impl.logging.ActivationSystemException ; import com.sun.corba.se.impl.oa.poa.BadServerIdHandler; import com.sun.corba.se.impl.orbutil.ORBConstants; import com.sun.corba.se.impl.orbutil.ORBUtility; import com.sun.corba.se.impl.util.Utility; public class ServerManagerImpl extends _ServerManagerImplBase implements BadServerIdHandler { // Using HashMap, since synchronization should be done by the calling // routines HashMap serverTable; Repository repository; CorbaTransportManager transportManager; int initialPort; ORB orb; ActivationSystemException wrapper; String dbDirName; boolean debug = false ; private int serverStartupDelay; ServerManagerImpl(ORB orb, CorbaTransportManager transportManager, Repository repository, String dbDirName, boolean debug) { this.orb = orb; wrapper = ActivationSystemException.get( orb, CORBALogDomains.ORBD_ACTIVATOR ) ; this.transportManager = transportManager; // REVISIT - NOT USED. this.repository = repository; this.dbDirName = dbDirName; this.debug = debug ; LegacyServerSocketEndPointInfo endpoint = orb.getLegacyServerSocketManager() .legacyGetEndpoint(LegacyServerSocketEndPointInfo.BOOT_NAMING); initialPort = ((SocketOrChannelAcceptor)endpoint) .getServerSocket().getLocalPort(); serverTable = new HashMap(256); // The ServerStartupDelay is the delay added after the Server registers // end point information. This is to allow the server to completely // initialize after ORB is instantiated. serverStartupDelay = ORBConstants.DEFAULT_SERVER_STARTUP_DELAY; String delay = System.getProperty( ORBConstants.SERVER_STARTUP_DELAY); if( delay != null ) { try { serverStartupDelay = Integer.parseInt( delay ); } catch ( Exception e ) { // Just use the default 1000 milliseconds as the default } } Class cls = orb.getORBData( ).getBadServerIdHandler(); if( cls == null ) { orb.setBadServerIdHandler( this ); } else { orb.initBadServerIdHandler() ; } orb.connect(this); ProcessMonitorThread.start( serverTable ); } public void activate(int serverId) throws ServerAlreadyActive, ServerNotRegistered, ServerHeldDown { ServerLocation location; ServerTableEntry entry; Integer key = new Integer(serverId); synchronized(serverTable) { entry = (ServerTableEntry) serverTable.get(key); } if (entry != null && entry.isActive()) { if (debug) System.out.println( "ServerManagerImpl: activate for server Id " + serverId + " failed because server is already active. " + "entry = " + entry ) ; throw new ServerAlreadyActive( serverId ); } // locate the server try { // We call getEntry here so that state of the entry is // checked for validity before we actually go and locate a server entry = getEntry(serverId); if (debug) System.out.println( "ServerManagerImpl: locateServer called with " + " serverId=" + serverId + " endpointType=" + IIOP_CLEAR_TEXT.value + " block=false" ) ; location = locateServer(entry, IIOP_CLEAR_TEXT.value, false); if (debug) System.out.println( "ServerManagerImpl: activate for server Id " + serverId + " found location " + location.hostname + " and activated it" ) ; } catch (NoSuchEndPoint ex) { if (debug) System.out.println( "ServerManagerImpl: activate for server Id " + " threw NoSuchEndpoint exception, which was ignored" ); } } public void active(int serverId, Server server) throws ServerNotRegistered { ServerTableEntry entry; Integer key = new Integer(serverId); synchronized (serverTable) { entry = (ServerTableEntry) serverTable.get(key); if (entry == null) { if (debug) System.out.println( "ServerManagerImpl: active for server Id " + serverId + " called, but no such server is registered." ) ; throw wrapper.serverNotExpectedToRegister() ; } else { if (debug) System.out.println( "ServerManagerImpl: active for server Id " + serverId + " called. This server is now active." ) ; entry.register(server); } } } public void registerEndpoints( int serverId, String orbId, EndPointInfo [] endpointList ) throws NoSuchEndPoint, ServerNotRegistered, ORBAlreadyRegistered { // orbId is ignored for now ServerTableEntry entry; Integer key = new Integer(serverId); synchronized (serverTable) { entry = (ServerTableEntry) serverTable.get(key); if (entry == null) { if (debug) System.out.println( "ServerManagerImpl: registerEndpoint for server Id " + serverId + " called, but no such server is registered." ) ; throw wrapper.serverNotExpectedToRegister() ; } else { if (debug) System.out.println( "ServerManagerImpl: registerEndpoints for server Id " + serverId + " called. This server is now active." ) ; entry.registerPorts( orbId, endpointList ); } } } public int[] getActiveServers() { ServerTableEntry entry; int[] list = null; synchronized (serverTable) { // unlike vectors, list is not synchronized ArrayList servers = new ArrayList(0); Iterator serverList = serverTable.keySet().iterator(); try { while (serverList.hasNext()) { Integer key = (Integer) serverList.next(); // get an entry entry = (ServerTableEntry) serverTable.get(key); if (entry.isValid() && entry.isActive()) { servers.add(entry); } } } catch (NoSuchElementException e) { // all done } // collect the active entries list = new int[servers.size()]; for (int i = 0; i < servers.size(); i++) { entry = (ServerTableEntry) servers.get(i); list[i] = entry.getServerId(); } } if (debug) { StringBuffer sb = new StringBuffer() ; for (int ctr=0; ctr<list.length; ctr++) { sb.append( ' ' ) ; sb.append( list[ctr] ) ; } System.out.println( "ServerManagerImpl: getActiveServers returns" + sb.toString() ) ; } return list; } public void shutdown(int serverId) throws ServerNotActive { ServerTableEntry entry; Integer key = new Integer(serverId); synchronized(serverTable) { entry = (ServerTableEntry) serverTable.remove(key); if (entry == null) { if (debug) System.out.println( "ServerManagerImpl: shutdown for server Id " + serverId + " throws ServerNotActive." ) ; throw new ServerNotActive( serverId ); } try { entry.destroy(); if (debug) System.out.println( "ServerManagerImpl: shutdown for server Id " + serverId + " completed." ) ; } catch (Exception e) { if (debug) System.out.println( "ServerManagerImpl: shutdown for server Id " + serverId + " threw exception " + e ) ; } } } private ServerTableEntry getEntry( int serverId ) throws ServerNotRegistered { Integer key = new Integer(serverId); ServerTableEntry entry = null ; synchronized (serverTable) { entry = (ServerTableEntry) serverTable.get(key); if (debug) if (entry == null) { System.out.println( "ServerManagerImpl: getEntry: " + "no active server found." ) ; } else { System.out.println( "ServerManagerImpl: getEntry: " + " active server found " + entry + "." ) ; } if ((entry != null) && (!entry.isValid())) { serverTable.remove(key); entry = null; } if (entry == null) { ServerDef serverDef = repository.getServer(serverId); entry = new ServerTableEntry( wrapper, serverId, serverDef, initialPort, dbDirName, false, debug); serverTable.put(key, entry); entry.activate() ; } } return entry ; } private ServerLocation locateServer (ServerTableEntry entry, String endpointType, boolean block) throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown { ServerLocation location = new ServerLocation() ; // if server location is desired, then wait for the server // to register back, then return location ORBPortInfo [] serverORBAndPortList; if (block) { try { serverORBAndPortList = entry.lookup(endpointType); } catch (Exception ex) { if (debug) System.out.println( "ServerManagerImpl: locateServer: " + "server held down" ) ; throw new ServerHeldDown( entry.getServerId() ); } String host = orb.getLegacyServerSocketManager() .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName(); location.hostname = host ; int listLength; if (serverORBAndPortList != null) { listLength = serverORBAndPortList.length; } else { listLength = 0; } location.ports = new ORBPortInfo[listLength]; for (int i = 0; i < listLength; i++) { location.ports[i] = new ORBPortInfo(serverORBAndPortList[i].orbId, serverORBAndPortList[i].port) ; if (debug) System.out.println( "ServerManagerImpl: locateServer: " + "server located at location " + location.hostname + " ORBid " + serverORBAndPortList[i].orbId + " Port " + serverORBAndPortList[i].port) ; } } return location; } private ServerLocationPerORB locateServerForORB (ServerTableEntry entry, String orbId, boolean block) throws InvalidORBid, ServerNotRegistered, ServerHeldDown { ServerLocationPerORB location = new ServerLocationPerORB() ; // if server location is desired, then wait for the server // to register back, then return location EndPointInfo [] endpointInfoList; if (block) { try { endpointInfoList = entry.lookupForORB(orbId); } catch (InvalidORBid ex) { throw ex; } catch (Exception ex) { if (debug) System.out.println( "ServerManagerImpl: locateServerForORB: " + "server held down" ) ; throw new ServerHeldDown( entry.getServerId() ); } String host = orb.getLegacyServerSocketManager() .legacyGetEndpoint(LegacyServerSocketEndPointInfo.DEFAULT_ENDPOINT).getHostName(); location.hostname = host ; int listLength; if (endpointInfoList != null) { listLength = endpointInfoList.length; } else { listLength = 0; } location.ports = new EndPointInfo[listLength]; for (int i = 0; i < listLength; i++) { location.ports[i] = new EndPointInfo(endpointInfoList[i].endpointType, endpointInfoList[i].port) ; if (debug) System.out.println( "ServerManagerImpl: locateServer: " + "server located at location " + location.hostname + " endpointType " + endpointInfoList[i].endpointType + " Port " + endpointInfoList[i].port) ; } } return location; } public String[] getORBNames(int serverId) throws ServerNotRegistered { try { ServerTableEntry entry = getEntry( serverId ) ; return (entry.getORBList()); } catch (Exception ex) { throw new ServerNotRegistered(serverId); } } private ServerTableEntry getRunningEntry( int serverId ) throws ServerNotRegistered { ServerTableEntry entry = getEntry( serverId ) ; try { // this is to see if the server has any listeners ORBPortInfo [] serverORBAndPortList = entry.lookup(IIOP_CLEAR_TEXT.value) ; } catch (Exception exc) { return null ; } return entry; } public void install( int serverId ) throws ServerNotRegistered, ServerHeldDown, ServerAlreadyInstalled { ServerTableEntry entry = getRunningEntry( serverId ) ; if (entry != null) { repository.install( serverId ) ; entry.install() ; } } public void uninstall( int serverId ) throws ServerNotRegistered, ServerHeldDown, ServerAlreadyUninstalled { ServerTableEntry entry = (ServerTableEntry) serverTable.get( new Integer(serverId) ); if (entry != null) { entry = (ServerTableEntry) serverTable.remove(new Integer(serverId)); if (entry == null) { if (debug) System.out.println( "ServerManagerImpl: shutdown for server Id " + serverId + " throws ServerNotActive." ) ; throw new ServerHeldDown( serverId ); } entry.uninstall(); } } public ServerLocation locateServer (int serverId, String endpointType) throws NoSuchEndPoint, ServerNotRegistered, ServerHeldDown { ServerTableEntry entry = getEntry( serverId ) ; if (debug) System.out.println( "ServerManagerImpl: locateServer called with " + " serverId=" + serverId + " endpointType=" + endpointType + " block=true" ) ; // passing in entry to eliminate multiple lookups for // the same entry in some cases return locateServer(entry, endpointType, true); } /** This method is used to obtain the registered ports for an ORB. * This is useful for custom Bad server ID handlers in ORBD. */ public ServerLocationPerORB locateServerForORB (int serverId, String orbId) throws InvalidORBid, ServerNotRegistered, ServerHeldDown { ServerTableEntry entry = getEntry( serverId ) ; // passing in entry to eliminate multiple lookups for // the same entry in some cases if (debug) System.out.println( "ServerManagerImpl: locateServerForORB called with " + " serverId=" + serverId + " orbId=" + orbId + " block=true" ) ; return locateServerForORB(entry, orbId, true); } public void handle(ObjectKey okey) { IOR newIOR = null; ServerLocationPerORB location; // we need to get the serverid and the orbid from the object key ObjectKeyTemplate oktemp = okey.getTemplate(); int serverId = oktemp.getServerId() ; String orbId = oktemp.getORBId() ; try { // get the ORBName corresponding to the orbMapid, that was // first registered by the server ServerTableEntry entry = getEntry( serverId ) ; location = locateServerForORB(entry, orbId, true); if (debug) System.out.println( "ServerManagerImpl: handle called for server id" + serverId + " orbid " + orbId) ; // we received a list of ports corresponding to an ORB in a // particular server, now retrieve the one corresponding // to IIOP_CLEAR_TEXT, and for other created the tagged // components to be added to the IOR int clearPort = 0; EndPointInfo[] listenerPorts = location.ports; for (int i = 0; i < listenerPorts.length; i++) { if ((listenerPorts[i].endpointType).equals(IIOP_CLEAR_TEXT.value)) { clearPort = listenerPorts[i].port; break; } } // create a new IOR with the correct port and correct tagged // components IIOPAddress addr = IIOPFactories.makeIIOPAddress( orb, location.hostname, clearPort ) ; IIOPProfileTemplate iptemp = IIOPFactories.makeIIOPProfileTemplate( orb, GIOPVersion.V1_2, addr ) ; if (GIOPVersion.V1_2.supportsIORIIOPProfileComponents()) { iptemp.add(IIOPFactories.makeCodeSetsComponent(orb)); iptemp.add(IIOPFactories.makeMaxStreamFormatVersionComponent()); } IORTemplate iortemp = IORFactories.makeIORTemplate(oktemp) ; iortemp.add( iptemp ) ; newIOR = iortemp.makeIOR(orb, "IDL:org/omg/CORBA/Object:1.0", okey.getId() ); } catch (Exception e) { throw wrapper.errorInBadServerIdHandler( e ) ; } if (debug) System.out.println( "ServerManagerImpl: handle " + "throws ForwardException" ) ; try { // This delay is required in case of Server is activated or // re-activated the first time. Server needs some time before // handling all the requests. // (Talk to Ken to see whether there is a better way of doing this). Thread.sleep( serverStartupDelay ); } catch ( Exception e ) { System.out.println( "Exception = " + e ); e.printStackTrace(); } throw new ForwardException(orb, newIOR); } public int getEndpoint(String endpointType) throws NoSuchEndPoint { return orb.getLegacyServerSocketManager() .legacyGetTransientServerPort(endpointType); } public int getServerPortForType(ServerLocationPerORB location, String endPointType) throws NoSuchEndPoint { EndPointInfo[] listenerPorts = location.ports; for (int i = 0; i < listenerPorts.length; i++) { if ((listenerPorts[i].endpointType).equals(endPointType)) { return listenerPorts[i].port; } } throw new NoSuchEndPoint(); } }