| /* |
| * 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(); |
| } |
| |
| } |